👻
SAM template で public に公開する S3 bucket を書く
AWS のサンプルコードを動かしていたんだけど、コードが S3 の ACL まわりのアップデート以前のもので、 CloudFormation Stack がデプロイできてなかった
S3 のアプデ
サンプルコード
エラー
エラーメッセージは
Resource handler returned message: "Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting
で、ウェブサイトの静的ファイルを入れる bucket を作るところでエラーになってた
エラー文の意味は
- S3 bucket の ACL (access control list) の設定で、
- ObjectOwnership の項目が BucketOwnerEnforced になってるけどそれはだめだよ
調査
ここで template のコードで S3 bucket を設定しているところを見てみると、
S3WebSite:
Type: "AWS::S3::Bucket"
Properties:
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
とあって、どこにも ObjectOwnership の話が書いてなくてハテナになった。S3 のアップデートはというと、
by default have ...(中略)... access control lists (ACLs) disabled
で、つまりこのアップデート以降はデフォルトで S3 の ACL が無効化された状態になる。で、ACL 無効化と BucketOwnerEnforced の関係はなにかというと、
ACL が無効
= bucket 内の object の所有者は bucket の所有者
= ObjectOwnerShip (object の所有者) が
BucketOwnerEnforced (bucket の所有者に強制される)
というふうなので、 テンプレートに何も指定していないと bucket の ObjectOwnerShip が BucketOwnerEnforced になる。ACL が有効だと、たとえば bucket 内にファイルがあったとしても、bucket の所有者 A さんと ファイル (=object) の所有者 B さんが異なり、自分が所有している bucket の中にあるファイルでもアクセス権がない、ということが起こりうる。
対処
この回答の通りにやるとデプロイできるようになる
いちおう貼り付け
S3WebSite:
Type: "AWS::S3::Bucket"
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: false
RestrictPublicBuckets: false
OwnershipControls:
Rules:
- ObjectOwnership: ObjectWriter
WebsiteConfiguration:
IndexDocument: index.html
S3WebSiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3WebSite
PolicyDocument:
Statement:
- Sid: PublicReadGetObject
Effect: Allow
Principal: "*"
Action:
- s3:GetObject
Resource: !Sub ${S3WebSite.Arn}/*
diff はこう
< AccessControl: PublicRead
---
> PublicAccessBlockConfiguration:
> BlockPublicAcls: false
> BlockPublicPolicy: false
> IgnorePublicAcls: false
> RestrictPublicBuckets: false
> OwnershipControls:
> Rules:
> - ObjectOwnership: ObjectWriter
172a180,191
> S3WebSiteBucketPolicy:
> Type: AWS::S3::BucketPolicy
> Properties:
> Bucket: !Ref S3WebSite
> PolicyDocument:
> Statement:
> - Sid: PublicReadGetObject
> Effect: Allow
> Principal: "*"
> Action:
> - s3:GetObject
> Resource: !Sub ${S3WebSite.Arn}/*
Discussion