使用Terraform部署S3网站遇AccessControlListNotSupported错误求助
解决S3部署时的AccessControlListNotSupported错误
你的错误根源是S3对象所有权模式与ACL使用不匹配,以及资源创建顺序的问题。以下是具体修复步骤:
原因分析
你设置了BucketOwnerPreferred的对象所有权,该模式本身支持ACL,但你的aws_s3_object资源未依赖权限配置资源,导致上传对象时Bucket的ACL规则还未生效;同时当前AWS官方更推荐用Bucket Policy替代ACL来管理公共访问,尤其是静态网站场景。
方案1:修复现有ACL配置
调整资源依赖顺序,确保权限配置完成后再上传对象:
resource "aws_s3_object" "object" { for_each = fileset("assets", "**") bucket = aws_s3_bucket.s3.id key = each.key source = "assets/${each.key}" acl = "public-read" etag = filemd5("assets/${each.key}") # 添加依赖,确保权限配置先完成 depends_on = [ aws_s3_bucket_acl.s3_acl, aws_s3_bucket_ownership_controls.s3_ownership ] }
同时确认你的AWS账号没有强制开启Bucket ACL禁用的组织策略,这也可能触发该错误。
方案2:改用Bucket Policy(推荐)
按照AWS最新最佳实践,使用Bucket Policy代替ACL,同时设置更安全的BucketOwnerEnforced对象所有权(当前S3默认模式):
- 删除
aws_s3_bucket_acl资源,修改对象所有权和公共访问块:
resource "aws_s3_bucket_ownership_controls" "s3_ownership" { bucket = aws_s3_bucket.s3.id rule { object_ownership = "BucketOwnerEnforced" # 改为强制桶所有者控制 } } resource "aws_s3_bucket_public_access_block" "s3_access" { bucket = aws_s3_bucket.s3.id block_public_acls = true # 禁用ACL,匹配BucketOwnerEnforced模式 block_public_policy = false ignore_public_acls = true restrict_public_buckets = false }
- 添加Bucket Policy允许公共访问静态网站内容:
resource "aws_s3_bucket_policy" "s3_policy" { bucket = aws_s3_bucket.s3.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = "*" Action = "s3:GetObject" Resource = "${aws_s3_bucket.s3.arn}/*" } ] }) depends_on = [aws_s3_bucket_ownership_controls.s3_ownership] }
- 修改
aws_s3_object,移除acl字段:
resource "aws_s3_object" "object" { for_each = fileset("assets", "**") bucket = aws_s3_bucket.s3.id key = each.key source = "assets/${each.key}" etag = filemd5("assets/${each.key}") depends_on = [aws_s3_bucket_policy.s3_policy] }
这种方案更符合AWS安全最佳实践,彻底避免ACL相关的兼容性问题。
内容的提问来源于stack exchange,提问作者MozkaGit
相关产品推荐
相关产品推荐

