Skip to content

AccessControlListNotSupported エラーの解決(AWS S3 バケット ACL作成時)

問題の説明

Terraform で aws_s3_bucket_acl リソースをデプロイしようとすると、以下のエラーが発生します:

shell
Error: error creating S3 bucket ACL for bucket-name: AccessControlListNotSupported: The bucket does not allow ACLs
status code: 400

このエラーは2023年4月以降のAWSのセキュリティ変更が原因です。AWSはデフォルトでS3バケットのACL(アクセスコントロールリスト)を無効化するように変更しました。

背景

AWSはセキュリティ強化のため、以下を実施:

  • 新規バケットでのACLデフォルト無効化
  • オブジェクト所有権設定の導入
  • [BucketOwnerEnforced] がテラフォームのデフォルト設定

以下のドキュメントで変更が確認できます:
Amazon S3 セキュリティ変更 (2023年4月)

解決方法

方法 1: 所有権制御の設定(推奨)

aws_s3_bucket_ownership_controls リソースを追加し、オブジェクト所有権を適切に設定します:

hcl
resource "aws_s3_bucket_ownership_controls" "example" {
  bucket = aws_s3_bucket.my_bucket.id
  rule {
    object_ownership = "BucketOwnerPreferred" # ACLを有効にする設定
  }
}

resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.my_bucket.id
  acl    = "private"
  
  # 依存関係を明示(所有権設定が先に作成されることを保証)
  depends_on = [aws_s3_bucket_ownership_controls.example]
}

重要

リソースの作成順序が影響します。depends_on で所有権設定がACLより先に適用されるように強制してください。

方法 2: バケットポリシーを使用(AWS推奨)

ACLの代わりにバケットポリシーを使用する別アプローチ:

hcl
resource "aws_s3_bucket_policy" "example" {
  bucket = aws_s3_bucket.my_bucket.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = "*"
        Action    = "s3:GetObject"
        Resource  = "${aws_s3_bucket.my_bucket.arn}/*"
      }
    ]
  })
}

参考:AWS S3 バケットポリシーガイド

terraform-aws-modules/s3-bucket モジュール使用時

モジュールを使用している場合、以下の設定を追加:

hcl
module "s3_bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "~> 3.0"
  
  bucket = "my-bucket"
  
  # ACLを有効化する設定
  control_object_ownership = true
  object_ownership         = "BucketOwnerPreferred"
}

エラーの根本原因

解決策を理解するためのキーポイント:

  1. 所有権設定の不一致
    Terraformのデフォルトは BucketOwnerEnforced(ACL完全無効)だが、ACLリソースには互換性がない

  2. リソース適用順序問題
    ACLリソースが所有権設定より先に適用されるとエラーが発生

  3. 有効な所有権設定値
    ACLを使うには次の中から選択必須:

    • ObjectWriter
    • BucketOwnerPreferred

非推奨設定

BucketOwnerEnforced を設定したままACLを使用すると、常にエラーが発生します。両者は互換性がありません。

ベストプラクティス

  1. ACLよりバケットポリシーを優先
    セキュリティと細かな制御のため、ACLよりバケットポリシーの使用がAWSから推奨されています

  2. 所有権設定の明示的定義
    モジュール使用時でも control_object_ownership を常に設定することで動作を予測可能に

  3. リソース依存関係の管理
    depends_on で作成順序を制御し、所有権設定が確実に先に適用されるようにする