You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:04:54