Terraform部署S3静态网站遇403权限错误,求解决方案
问题
尝试用Terraform将前端部署到S3存储桶时,设置S3桶ACL和Policy时遇到403 AccessDenied错误,具体错误:
- PutBucketAcl: AccessDenied: 用户无权执行
s3:PutBucketAcl,因为BlockPublicAcls设置阻止了公共访问控制列表(ACLs)。 - PutBucketPolicy: AccessDenied: 用户无权执行
s3:PutBucketPolicy,因为BlockPublicPolicy设置阻止了公共策略。
已尝试的操作:
- 配置
aws_s3_bucket_public_access_block资源禁用公共ACL和策略的阻止设置 - 确保IAM用户拥有
s3:PutBucketAcl和s3:PutBucketPolicy权限 - 验证没有组织级策略阻止这些操作
Terraform版本:v1.5.7
Terraform代码
resource "random_pet" "frontend_name" {} resource "aws_s3_bucket" "frontend_bucket" { bucket = "frontend-bucket-${random_pet.frontend_name.id}" force_destroy = true } resource "aws_s3_bucket_acl" "frontend_acl" { bucket = aws_s3_bucket.frontend_bucket.id acl = "public-read" } resource "aws_s3_bucket_website_configuration" "frontend_website" { bucket = aws_s3_bucket.frontend_bucket.id index_document { suffix = "index.html" } } resource "aws_s3_bucket_public_access_block" "frontend_public_access_block" { bucket = aws_s3_bucket.frontend_bucket.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } resource "aws_s3_bucket_cors_configuration" "frontend_cors" { bucket = aws_s3_bucket.frontend_bucket.id cors_rule { allowed_methods = ["GET"] allowed_origins = ["*"] allowed_headers = ["*"] } } resource "null_resource" "s3_sync" { depends_on = [null_resource.build_frontend] provisioner "local-exec" { command = <<EOT AWS_PROFILE=${var.aws_profile} aws s3 sync ../frontend/dist/ s3://${aws_s3_bucket.frontend_bucket.id}/ EOT } } resource "aws_s3_bucket_policy" "frontend_bucket_policy" { bucket = aws_s3_bucket.frontend_bucket.id policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::${aws_s3_bucket.frontend_bucket.id}/*" } ] } POLICY }
错误日志
╷ │ Error: creating S3 Bucket (frontend-bucket-giving-unicorn) ACL: operation error S3: PutBucketAcl, https response error StatusCode: 403, RequestID: 8FPDNEDW1WNKTKS2, HostID: V4Bv6r2nOUjVdpK9hbKfo2CLEK9fBVou3Mnw1pp29vM6pabH47V6CSgNiZ2XW5tCLt3o2ljpDtA=, api error AccessDenied: User: arn:aws:iam::<removed>:user/Admin is not authorized to perform: s3:PutBucketAcl on resource: "arn:aws:s3:::frontend-bucket-giving-unicorn" because public access control lists (ACLs) are blocked by the BlockPublicAcls block public access setting. │ │ with module.frontend.aws_s3_bucket_acl.frontend_acl, │ on frontend/s3.tf line 8, in resource "aws_s3_bucket_acl" "frontend_acl": │ 8: resource "aws_s3_bucket_acl" "frontend_acl" { │ ╵ ╷ │ Error: putting S3 Bucket (frontend-bucket-giving-unicorn) Policy: operation error S3: PutBucketPolicy, https response error StatusCode: 403, RequestID: 8FP73W1TMVZZKQY1, HostID: 7pEKSxxeNBrKX9gif/qnpkl5yWJXmcbureAH5qGIJH6EJNZTaTfBaJNNiUP5non2ens+Z5bsyI8=, api error AccessDenied: User: arn:aws:iam::<removed>:user/Admin is not authorized to perform: s3:PutBucketPolicy on resource: "arn:aws:s3:::frontend-bucket-giving-unicorn" because public policies are blocked by the BlockPublicPolicy block public access setting. │ │ with module.frontend.aws_s3_bucket_policy.frontend_bucket_policy, │ on frontend/s3.tf line 50, in resource "aws_s3_bucket_policy" "frontend_bucket_policy": │ 50: resource "aws_s3_bucket_policy" "frontend_bucket_policy" { │ ╵
IAM用户(Admin)已配置全权限权限。
解决方案
1. 强制资源创建顺序
Terraform默认并行创建资源,导致设置ACL/Policy时,公共访问阻止设置尚未生效。需给ACL和Policy资源添加依赖,确保aws_s3_bucket_public_access_block先完成创建:
修改aws_s3_bucket_acl资源:
resource "aws_s3_bucket_acl" "frontend_acl" { bucket = aws_s3_bucket.frontend_bucket.id acl = "public-read" depends_on = [aws_s3_bucket_public_access_block.frontend_public_access_block] }
修改aws_s3_bucket_policy资源:
resource "aws_s3_bucket_policy" "frontend_bucket_policy" { bucket = aws_s3_bucket.frontend_bucket.id policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::${aws_s3_bucket.frontend_bucket.id}/*" } ] } POLICY depends_on = [aws_s3_bucket_public_access_block.frontend_public_access_block] }
2. 检查账户级公共访问设置
部分AWS环境默认启用账户级公共访问阻止,即使桶级设置关闭也会生效。登录AWS控制台操作:
- 进入S3控制台 → 左侧导航栏选择「Block public access (account settings)」
- 取消勾选
BlockPublicAcls和BlockPublicPolicy选项(需账户管理员权限)
3. 简化配置(可选)
静态网站托管无需同时配置ACL和Bucket Policy,删除aws_s3_bucket_acl资源,仅保留Bucket Policy即可实现公共访问,减少配置冲突。
4. 验证IAM权限范围
确认IAM用户的权限策略中,s3:PutBucketAcl和s3:PutBucketPolicy的资源范围包含目标桶(可使用"arn:aws:s3:::*"覆盖所有桶),避免资源ARN限制导致权限不足。
内容的提问来源于stack exchange,提问作者Jordan Pownall
相关产品推荐
相关产品推荐

