Skip to content

S3存储桶ACL错误

问题描述

当用户尝试使用 Terraform 的 aws_s3_bucket_acl 资源配置 AWS S3 存储桶访问控制列表(ACL)时,会遇到以下错误:

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

该问题源于 AWS 在 2023年4月的安全更新:S3存储桶默认禁用ACL功能。新创建的存储桶若未明确配置所有权设置,Terraform的资源操作将被拒绝。

根本原因:

  • AWS默认启用了"BucketOwnerEnforced"所有权模式(禁用ACL)
  • Terraform中的aws_s3_bucket_acl资源需要"ObjectWriter"或"BucketOwnerPreferred"模式支持
  • 资源创建顺序问题:Terraform可能先创建ACL,后设置所有权控制

解决方案

方法1:添加所有权控制资源(推荐)

通过添加aws_s3_bucket_ownership_controls资源强制启用ACL支持:

hcl
# 先创建所有权控制资源
resource "aws_s3_bucket_ownership_controls" "ownership" {
  bucket = aws_s3_bucket.example.id  # 替换为您的存储桶ID
  rule {
    object_ownership = "ObjectWriter"  # 或 "BucketOwnerPreferred"
  }
}

# 再创建ACL资源并声明依赖
resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.example.id
  acl    = "private"
  
  # 确保所有权控制先创建
  depends_on = [aws_s3_bucket_ownership_controls.ownership] 
}

关键点

  • 顺序依赖depends_on强制先配置所有权控制
  • 有效模式:仅ObjectWriterBucketOwnerPreferred支持ACL
  • 适用场景:需要保留旧版ACL配置的系统

方法2:使用Terraform S3模块简化配置

若使用官方模块terraform-aws-modules/s3-bucket/aws,只需设置模块参数:

hcl
module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-bucket"
  acl    = "private"
  
  # 启用所有权控制
  control_object_ownership = true
  object_ownership         = "BucketOwnerPreferred"
}

模块提示

  • control_object_ownership=true 自动禁止"BucketOwnerEnforced"模式
  • 模块自动处理资源依赖,无需手动添加depends_on

方法3:改用存储桶策略(AWS推荐)

AWS官方建议优先使用存储桶策略替代ACL:

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

安全建议

  1. 最小权限原则:策略仅授予必要权限
  2. 审核所有公有访问配置
  3. 彻底移除遗留ACL配置

故障排除流程

最佳实践

  1. 禁用ACL:通过配置完全禁用ACL以保证安全

    hcl
    # 强制执行策略禁止ACL
    resource "aws_s3_bucket_ownership_controls" "no_acl" {
      bucket = aws_s3_bucket.example.id
      rule { object_ownership = "BucketOwnerEnforced" }
    }
  2. 迁移计划

    • 阶段1:添加所有权控制维持现有系统
    • 阶段2:逐步用存储桶策略替换ACL配置
    • 阶段3:完全禁用ACL功能
  3. 审计现有配置

    • 检查所有S3存储桶的ObjectOwnership设置
    • 识别仍然使用ACL的资源
    • 使用AWS Trusted Advisor扫描公开访问风险

遵循这些指导可解决AccessControlListNotSupported错误,同时确保配置符合AWS最新安全标准。