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

S3静态网站存储桶Bucket Policy配置403错误排查求助

排查S3存储桶Bucket Policy配置403错误原因

问题描述

创建用于静态网站托管的S3存储桶成功,但配置Bucket Policy时返回403 AccessDenied错误:

Error: putting S3 Bucket (serengatti01bhg) Policy: operation error S3: PutBucketPolicy, https response error StatusCode: 403, RequestID: 5TA4MQJ2Y0FNJ5FA, HostID: E+qj6u+HWZthQlkvOuQQRqE+pfdFOfPoceulLyDxy/70UCW7dVQU+X2GSdNs1a65LuLq9yWErOU=, api error AccessDenied: Access Denied

Terraform计划执行结果为Plan: 2 to add, 0 to change, 0 to destroy,Bucket Policy包含四条语句,需保留现有策略(因需禁用公共访问),现需排查错误原因。

Terraform配置代码

resource "aws_s3_bucket" "test01" {
  bucket = "serengatti01bhg"

  tags = {
    Name = "serengatti01bhg"
  }
}

resource "aws_s3_bucket_policy" "test01_policy" {
  bucket = aws_s3_bucket.test01.id

  policy = jsonencode(
    {
      Version = "2012-10-17"
      Statement = [
        {
          Sid       = "pc_access"
          Effect    = "Allow"
          Action    = "s3:*"
          Principal = "*"
          Resource = [
            aws_s3_bucket.test01.arn,
            "${aws_s3_bucket.test01.arn}/*"
          ]
          Condition = {
            "IpAddress" = {
              "aws:SourceIp" = "my public ip"
            }
          }
        },

        {
          Sid    = "admins_access"
          Effect = "Allow"
          Action = "s3:*"
          Principal = {
            AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/ak"
          }
          Resource = [
            aws_s3_bucket.test01.arn,
            "${aws_s3_bucket.test01.arn}/*"
          ]
        },

        {
          Sid       = "ssl_policy"
          Effect    = "Deny"
          Principal = "*"
          Action    = "s3:*"
          Resource = [
            aws_s3_bucket.test01.arn,
          ]
          Condition = {
            Bool = {
              "aws:SecureTransport" = "false"
            }
          }
        },

        {
          Sid       = "PublicReadGetObject"
          Effect    = "Allow"
          Principal = "*"
          Action    = "s3:GetObject"
          Resource = [
            "${aws_s3_bucket.test01.arn}/*",
          ]
        }
      ]
    }
  )
}

错误原因排查方向

1. 执行Terraform的IAM身份权限不足

当前执行Terraform的IAM实体(用户/角色)必须拥有s3:PutBucketPolicy权限,且没有被任何Deny策略限制。即使是管理员权限,也需确认是否存在基于资源或身份的Deny规则阻止该操作。

2. 桶的公共访问设置冲突

你的策略中包含PublicReadGetObject语句(允许所有用户执行s3:GetObject),但如果存储桶的桶级公共访问控制中开启了以下任一选项,会直接阻止添加包含公共访问的Bucket Policy,触发403错误:

  • Block public access to buckets and objects granted through bucket policies
  • Block public access to buckets and objects granted through any access control lists (ACLs)
    注意:你提到“需禁用公共访问”,但当前策略中的PublicReadGetObject本质是允许公共访问,这本身存在需求冲突,需明确实际需求。

3. Deny语句限制了PutBucketPolicy操作

第三个语句ssl_policy会Deny所有非HTTPS的s3:*操作到存储桶本身。如果Terraform执行PutBucketPolicy时使用的是HTTP请求(尽管现在大部分场景是HTTPS),会被该策略拦截,返回403。可临时注释该语句测试是否能成功添加策略,验证是否为此原因。

4. IAM用户ARN配置错误

第二个语句admins_access中引用了data.aws_caller_identity.current.account_id,若Terraform配置中未定义该数据源:

data "aws_caller_identity" "current" {}

会导致账号ID为空,生成无效的IAM用户ARN,可能引发策略验证失败,间接导致403错误。

验证步骤

  1. 切换到拥有完整S3权限的IAM实体执行Terraform,排除权限不足问题。
  2. 检查存储桶的公共访问设置,若开启了阻止公共策略的选项,需临时关闭后添加策略,再根据实际需求调整策略或公共访问设置。
  3. 临时注释ssl_policy语句,重新执行terraform apply,确认是否能成功添加策略。
  4. 确认data.aws_caller_identity.current已在Terraform配置中定义,且生成的IAM用户ARN正确。

内容的提问来源于stack exchange,提问作者user23350878

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:35:04