同时创建AWS S3桶与桶策略时遇Access Denied错误求助
解决Terraform同时创建S3桶与桶策略时的Access Denied错误
问题场景
编写Web托管用的AWS S3桶Terraform脚本时,一次性创建S3桶、网站配置、公共访问控制块及桶策略,会触发Access Denied错误。但先执行terraform apply创建桶和基础配置,再单独添加桶策略执行apply则无报错。曾考虑调整依赖关系,但不确定如何配置。
问题原因
AWS S3的公共访问控制块(Public Access Block)配置需要先生效,才能设置允许公共访问的桶策略。Terraform默认的资源依赖中,aws_s3_bucket_policy仅依赖桶的存在,不会等待aws_s3_bucket_public_access_block配置完成。即使我们显式将公共访问控制设为允许,若策略先于控制块生效,AWS仍会因默认的公共策略限制拒绝操作,导致权限错误。
解决方案
通过调整资源依赖关系,确保公共访问控制配置完成后再应用桶策略,同时优化策略文档的资源引用方式:
- 优化IAM策略文档的资源引用:用桶的ARN替代硬编码域名,让Terraform自动建立策略文档与桶的依赖,确保桶创建后才生成策略内容。
- 添加显式依赖:给
aws_s3_bucket_policy添加depends_on,强制等待公共访问控制块配置完成。
修改后的完整代码
resource "aws_s3_bucket" "web_hosting_bucket" { bucket = var.domain_name } resource "aws_s3_bucket_website_configuration" "web_hosting_bucket_config" { bucket = aws_s3_bucket.web_hosting_bucket.id index_document { suffix = "index.html" } error_document { key = "index.html" } } resource "aws_s3_bucket_public_access_block" "web_hosting_bucket_public_access" { bucket = aws_s3_bucket.web_hosting_bucket.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } resource "aws_s3_bucket_policy" "web_hosting_bucket_policy" { bucket = aws_s3_bucket.web_hosting_bucket.id policy = data.aws_iam_policy_document.iam_policy_document.json # 显式依赖公共访问控制块,确保配置完成后再应用策略 depends_on = [aws_s3_bucket_public_access_block.web_hosting_bucket_public_access] } data "aws_iam_policy_document" "iam_policy_document" { version = "2012-10-17" statement { sid = "PublicReadGetObject" effect = "Allow" actions = ["s3:GetObject"] principals { type = "AWS" identifiers = ["*"] } # 用桶的ARN替代硬编码域名,自动建立依赖关系 resources = [ "${aws_s3_bucket.web_hosting_bucket.arn}/*", ] } }
验证方法
直接执行terraform apply,此时Terraform会按以下顺序执行:
- 创建S3桶
- 配置网站设置
- 配置公共访问控制块
- 生成IAM策略文档
- 应用桶策略
这样就能避免因依赖顺序导致的Access Denied错误。
内容的提问来源于stack exchange,提问作者Jinwoo An
相关产品推荐
相关产品推荐

