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

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-read ACL,也会被系统拦截。

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-read ACL正常生效;
  • 添加depends_on明确资源依赖顺序,避免ACL在Block Public Access配置完成前被设置;
  • 必须保留原有的权限策略和静态网站配置,保证权限完整性与托管功能正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:36:22