Terraform中AWS S3非弃用ACL配置失效,弃用版本正常
问题描述
使用Terraform v1.2.2搭配AWS Provider v3.75.2部署CloudFront静态UI的S3桶时,原配置中aws_s3_bucket内的acl = "public-read"可正常运行,但该配置已被弃用。替换为aws_s3_bucket_acl资源后,S3桶的ACL丢失,浏览器无法加载资源,出现权限问题。
原可用配置
resource "aws_s3_bucket" "admin-app-s3" { bucket = "admin-app-${var.environment}" acl = "public-read" } resource "aws_s3_bucket_policy" "admin-app-s3-policy1" { bucket = aws_s3_bucket.admin-app-s3.id policy = jsonencode({ Version = "2012-10-17" Id = "admin-app-${var.environment}-policy1" Statement = [ { Sid = "Stmt##########" Effect = "Allow" Principal = { AWS = ["arn:aws:iam::##########:user/gitlab-deployments"] } Action = "s3:*" Resource = "arn:aws:s3:::admin-app-${var.environment}/*" }, { Sid = "Stmt##########" Effect = "Allow" Principal = "*" Action = ["s3:GetObject","s3:GetObjectVersion"] Resource = "arn:aws:s3:::admin-app-${var.environment}/*" } ] }) } resource "aws_s3_bucket_website_configuration" "admin-app-configuration1" { bucket = aws_s3_bucket.admin-app-s3.bucket index_document { suffix = "index.html" } error_document { key = "index.html" } }
替换后的配置(失效)
resource "aws_s3_bucket" "admin-app-s3" { bucket = "admin-app-${var.environment}" } resource "aws_s3_bucket_acl" "acl1" { bucket = aws_s3_bucket.admin-app-s3.id acl = "public-read" }
原因分析与解决方案
这不是Terraform的问题,核心是AWS S3权限机制变化及配置遗漏导致:
1. Block Public Access默认拦截公共ACL
AWS当前默认对新创建的S3桶开启Block Public Access规则,会直接覆盖ACL的公共权限设置:
- 原配置使用旧版
aws_s3_bucket的acl参数时,AWS Provider v3.x的旧行为会自动关闭对应的Block Public Access规则,确保public-read生效; - 改用独立的
aws_s3_bucket_acl资源后,需手动关闭Block Public Access,否则即使设置了public-readACL,也会被系统拦截。
2. 关键配置遗漏
替换后的配置未保留原有的aws_s3_bucket_policy和aws_s3_bucket_website_configuration:
aws_s3_bucket_policy中包含允许所有用户执行s3:GetObject的规则,这是浏览器能加载资源的核心权限之一;aws_s3_bucket_website_configuration负责配置静态网站托管,缺失会导致桶无法作为静态站点提供服务。
修复后的完整配置
resource "aws_s3_bucket" "admin-app-s3" { bucket = "admin-app-${var.environment}" } # 关闭Block Public Access,确保公共ACL生效 resource "aws_s3_bucket_public_access_block" "admin-app-block" { bucket = aws_s3_bucket.admin-app-s3.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } resource "aws_s3_bucket_acl" "acl1" { bucket = aws_s3_bucket.admin-app-s3.id acl = "public-read" # 依赖公共访问配置完成后再设置ACL,避免时序问题 depends_on = [aws_s3_bucket_public_access_block.admin-app-block] } # 保留原有的权限策略 resource "aws_s3_bucket_policy" "admin-app-s3-policy1" { bucket = aws_s3_bucket.admin-app-s3.id policy = jsonencode({ Version = "2012-10-17" Id = "admin-app-${var.environment}-policy1" Statement = [ { Sid = "Stmt##########" Effect = "Allow" Principal = { AWS = ["arn:aws:iam::##########:user/gitlab-deployments"] } Action = "s3:*" Resource = "arn:aws:s3:::admin-app-${var.environment}/*" }, { Sid = "Stmt##########" Effect = "Allow" Principal = "*" Action = ["s3:GetObject","s3:GetObjectVersion"] Resource = "arn:aws:s3:::admin-app-${var.environment}/*" } ] }) } # 保留静态网站托管配置 resource "aws_s3_bucket_website_configuration" "admin-app-configuration1" { bucket = aws_s3_bucket.admin-app-s3.bucket index_document { suffix = "index.html" } error_document { key = "index.html" } }
关键说明
- 通过
aws_s3_bucket_public_access_block关闭所有阻止公共访问的规则,确保public-readACL正常生效; - 添加
depends_on明确资源依赖顺序,避免ACL在Block Public Access配置完成前被设置; - 必须保留原有的权限策略和静态网站配置,保证权限完整性与托管功能正常。
内容的提问来源于stack exchange,提问作者Miguel Conde
相关产品推荐
相关产品推荐

