概要
今まで使っていたCloudFormationテンプレートを利用したら、Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting
というエラーになり失敗しました。本記事ではその原因と解決方法を記載します。
エラー内容:
以下がエラー内容です。
Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting (Service: Amazon S3; Status Code: 400; Error Code: InvalidBucketAclWithObjectOwnership; Request ID: XXXXXXXXXX; S3 Extended Request ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=; Proxy: null)
S3のオブジェクト所有者(ObjectOwnership
)を「バケット所有者の強制」(BucketOwnerEnforced
)の設定にしている状態で、BucketにACLを設定することはできない、というのがエラー内容です。
あれ、「バケット所有者の強制」の設定なんかしていないんだけどなぁ〜
って思ったら、4/28からObjectOwnership
はデフォルトで「バケット所有者の強制」になっているとのこと!
Amazon S3 が新規バケットすべてに 2 つのセキュリティベストプラクティスをデフォルトで適用開始
このデフォルトの設定ではACLはオフになるらしいです。
そのため、「バケット所有者の強制」なのに「ACL有効」なんて、そんなのは無理だよ!って怒られます。
解決方法
以下はAWSのrePost記事です。この通りに実施すると解決します。
CloudFormationの「バケットは ObjectOwnership の BucketOwnerEnforced 設定で ACL を設定できません」というエラーを修正する方法を教えてください。
つまり、所有者に明示的に「ObjectWriter
」を追加すればOKです。
これによりデフォルトの「バケット所有者の強制」ではなく「オブジェクトライター」になるので、ACLを呼び出してもエラーになりません。
変更前
BucketLog:
Type: AWS::S3::Bucket
Properties:
AccessControl: LogDeliveryWrite
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
変更後
BucketLog:
Type: AWS::S3::Bucket
Properties:
AccessControl: LogDeliveryWrite
OwnershipControls: #追加
Rules: #追加
- ObjectOwnership: ObjectWriter #追加
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
サンプルYAML比較
以下、
・2023/4以前に作成したS3 BucketFileとLog
および
・2023/8に作成したS3 BucketFileとLog
のYAMLとマネジメントコンソール画面を記します。
S3 Bucket Fileの比較(ACLにPrivate
設定したFileの場合)
1: 2023/4以前に作成したS3 BucketFile
BucketFile:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
AccessControl: Private
LoggingConfiguration:
DestinationBucketName: !Sub ${EnvTag}-${SysTag}-${BucketNameLog}
LogFilePrefix: !Sub ${BucketNameFile}/
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
↓↓↓
・マネコンから確認
→2023/4前のものなので、デフォルトでオブジェクト所有者が「オブジェクトライター」になっていることがわかります=ACL は有効とあり
2: 2023/8に作成したS3 BucketFile
BucketFile:
Type: AWS::S3::Bucket
# DeletionPolicy: Retain
Properties:
AccessControl: Private
LoggingConfiguration:
DestinationBucketName: !Sub ${SysTag}-${BucketNameLog}
LogFilePrefix: !Sub ${BucketNameFile}/
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
↓↓↓
→2023/8なので、デフォルトでオブジェクト所有者が「バケット所有者の強制」になっていることがわかります=ACL は無効とあり
Private
に設定した場合は、ACLが無効な状態と実質同じとなり(=オブジェクトへのアクセスはバケット所有者に制限されるため)、上述のエラーは発生しません。
「バケット所有者の強制が適用される場合は、バケットポリシーを使用してアクセスを制御」します。つまり、ACLはS3バケット内のデータへのアクセス許可に影響を与えなくなったということ。デフォルトで無効になっている理由がわかりますね。
コンソールから見ても「ACL無効」→「バケット所有者の強制」ということがわかります
S3 BucketLogの比較(ACLにLogDeliveryWrite
を設定したLogの場合)
3: 2023/4以前に作成したS3 BucketLog
BucketLog:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
AccessControl: LogDeliveryWrite
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
↓↓↓
・マネコンから確認
→2023/4以前なので、デフォルトでオブジェクト所有者が「オブジェクトライター」になっていることがわかります=ACL は有効とあり
ちなみに、LogDeliveryWrite
は、アクセスログのために作られる外部ユーザー(awslogsdelivery
)にバケットへのREAD/WRITEアクセス権限を付与する設定です。
4: 2023/8に作成したS3 BucketLog
BucketLog:
Type: AWS::S3::Bucket
# DeletionPolicy: Retain
Properties:
AccessControl: LogDeliveryWrite
OwnershipControls:
Rules:
- ObjectOwnership: ObjectWriter
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
↓↓↓
・マネコンから確認
→2023/8作成。ObjectWriter
を指定してあげれば、オブジェクト所有者が「オブジェクトライター」になっていることがわかります=ACL は有効とあり
逆に、ここでObjectOwnership
に何も設定しないと、デフォルトのままとなり、上述のエラーが発生してしまいます。
ちなみに、ACLを有効にしたい場合、ObjectOwnership
には以下の2種類があります。
- 「希望するバケット所有者」
- 「オブジェクトライター」
上記のテンプレート例ではいずれも「オブジェクトライター」を選んでいますが、「希望するバケット所有者」 もあります。