AWS CloudFront 和 Amazon S3 是很常見的搭配組合,而這篇的案例是期望 Amazon S3 可以 cross account 又要能使用 custom domain presigned URL,簡單實用的組合技。我想應該有許多人已經知道怎麼處理,而這篇就是把整個步驟再重點整理一下,應該是沒有太多給各位驚艷的地方 XD …
Requirements
- 獨立的 AWS Account 擁有 CloudFront 和 Route 53
- 一或多個 AWS Account 各自擁有 Amazon S3 的操作權限
- Amazon S3 不能裸奔在 Internet,僅允許 users 從 CloudFront 存取
- Amazon S3 presigned URLs 時要能使用 custom domain
Architecture
大概理了一下架構,會使用到 Route 53, CloudFront 和 Amazon S3 這三個服務,而 CloudFront 需要串接存在於多個不同 AWS Accounts 的 Amazon S3,為了避免 Amazon S3 獨自外露在 Internet 則還會搭配 Amazon S3 bucket policy 和 CloudFront OAI (Origin Access Identity) 處理兩邊的權限。
Tips for AWS CloudFront and Route 53 (Account A)
CloudFront Origin access identities
CloudFront OAI 用於產生一個 13 碼由英數組成的 identity ID (e.g. EXV4Q9MG1RS1F
) 待會給 CloudFront distribution 存取 Amazon S3 使用
1 個 CloudFront distribution 只能 attach 1 個 OAI,而 1 個 OAI 可以有多個 CloudFront distribution,大量使用 OAI 時先閱讀 Quotas
CloudFront distribution
- Origin domain:<bucket-name>.s3.<region>.amazonaws.com
domain name 加上 region 是為了讓 CloudFront 在尋找 Amazon S3 時不再 307 跳轉到正確的 region,可參考「CloudFront 接 S3 Static Website 時出現 307 轉址」
- S3 bucket access:Yes use OAI (bucket can restrict access to only CloudFront) with CloudFront OAI
雖然 CloudFront 支援直接加 Bucket policy 到 Amazon S3 但由於是 cross account 的關係,預設 CloudFront 是沒有權限 cross-account 訪問 Account B,所以這裡選「No, I will update the bucket policy」待會手動在 Amazon S3 加上。
- Alternate domain name (CNAME)
輸入要 custom domain 的網址,這有點像是 Apache 的 Name-based Virtual Host
Route 53
建立 hosted-zone 並將 CNAME 指向 CloudFront domain name. e.g. <example>.cloudfront.net
Tips for Amazon S3 (Account B)
Amazon S3 維持 Block all public access:On 的狀態,透過 Bucket policy 開放給 CloudFront 來存取:
{
"Version": "2012-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXV4Q9MG1RS1F" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket-name>/*"
}
]
}
這條 Bucket policy 僅開放給有 OAI EXV4Q9MG1RS1F
的 CloudFront,有了這條後 Bucket 可以在完全封閉的情況下開放出去
Testing
完成後可以測試兩條路:
- Allow – 由 CloudFront + Route 53 提供的 custom domain 或是 CloudFront domain
- Allow – S3 presigned URL 的 domain name 換成 custom domain
- Deny – 由 Amazon S3 提供的 Static website domain. e.g. http://<bucket-name>.s3-website-<region>.amazonaws.com