Closed8

terraform の aws_s3_bucket_acl を作ろうとしたら AccessControlListNotSupported が発生した

dyokoo3dyokoo3

こんな感じでコンソールから作成されたS3バケットをインポートしようとした

resource "aws_s3_bucket_acl" "sample" {
  depends_on = [
    aws_s3_bucket_public_access_block.sample,
  ]
  bucket = aws_s3_bucket.sample.id
  acl    = "private"
}

resource "aws_s3_bucket_ownership_controls" "sample" {
  bucket = aws_s3_bucket.sample.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}
dyokoo3dyokoo3

terraform applyしたらエラーが出た

│ Error: updating S3 bucket ACL (xxxxx): AccessControlListNotSupported: The bucket does not allow ACLs
│ 	status code: 400, request id: xxxxx, host id:xxxxx
│
│   with module.aws_s3_bucket_acl.sample,
│   on ../../modules/s3.tf line 244, in resource "aws_s3_bucket_acl" "xxxxx":244: resource "aws_s3_bucket_acl" "xxxxx" {
dyokoo3dyokoo3

aws provider 5.0 から acl の記述方法が変わったらしい

大元のPR:

The workaround, as [1] suggests, is setting the acl attribute to bucket-owner-full-control. I think it's quite confusing to have to specify an ACL to use no ACL; if I don't want to use ACLs, I simply don't specify acl attribute at all.

https://github.com/hashicorp/terraform-provider-aws/pull/27197

アップグレードガイド:

The acl attribute no longer has a default value. Previously this was set to private when omitted. Objects requiring a private ACL should now explicitly set this attribute.

https://registry.terraform.io/providers/BigEyeLabs/aws-test/latest/docs/guides/version-5-upgrade#resourceaws_s3_object

dyokoo3dyokoo3

BucketOwnerEnforcedの場合は acl の行を削除すればOK

resource "aws_s3_bucket_acl" "sample" {
  depends_on = [
    aws_s3_bucket_public_access_block.sample,
  ]
  bucket = aws_s3_bucket.sample.id
  -  acl    = "private"
}

resource "aws_s3_bucket_ownership_controls" "sample" {
  bucket = aws_s3_bucket.sample.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}
No changes. Your infrastructure matches the configuration.

追記

aws_s3_bucket_acl自体を Terraform の管理外にしたほうが良さそう。
https://zenn.dev/link/comments/80e69e76def139

dyokoo3dyokoo3

挙動がよくわからないので、object_ownershipObjectWriteracl ="private"なしを試したらエラーになった

resource "aws_s3_bucket" "sample" {
  bucket = "sample"
}

resource "aws_s3_bucket_public_access_block" "sample" {
  bucket = aws_s3_bucket.sample.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_acl" "sample" {
  bucket = aws_s3_bucket.sample.id
}

resource "aws_s3_bucket_ownership_controls" "sample" {
  bucket = aws_s3_bucket.sample.id
  rule {
    object_ownership = "ObjectWriter"
  }
}

メッセージ

│ Error: creating S3 Bucket (sample) ACL: operation error S3: PutBucketAcl, https response error StatusCode: 400, RequestID: xxxx, HostID: xxx, api error MissingSecurityHeader: Your request was missing a required header
dyokoo3dyokoo3

object_ownershipのデフォルトはBucketOwnerEnforcedのはずだから以下のようにしてみてもエラーになった

resource "aws_s3_bucket" "sample" {
  bucket = "sample-samplesamplesample-sample-sample-sample"
}

resource "aws_s3_bucket_acl" "sample" {
  bucket = aws_s3_bucket.sample.id
}

作成されたコンソール画面上でももBucketOwnerEnforcedになってる

なんでaws_s3_bucket_ownership_controlsを指定したときと等価じゃないんだ?

このスクラップは2023/10/12にクローズされました