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

Terraform配置Django静态文件S3桶遇权限策略错误求助

解决Terraform配置AWS S3静态文件桶的策略错误

看起来你踩了两个典型的Terraform S3配置坑,我来帮你理清问题并修正代码:

问题根源分析

  1. 桶策略引用错误:你在aws_s3_bucket_policy资源里错误引用了IAM用户的策略文档(data.aws_iam_policy_document.integrations_lite_staticfiles_s3_user_policy.json),但这个文档是给IAM用户授权用的,没有包含S3桶策略必需的Principal字段,导致AWS返回Missing required field Principal错误。
  2. 对aws_s3_bucket_policy资源的误解:这个资源本身不需要principals参数,所有策略逻辑都应该通过policy字段传入的JSON文档来定义,直接加principals会被Terraform判定为无效参数。

修正后的完整代码

# 创建托管静态文件的S3桶
resource "aws_s3_bucket" "integrations_lite_staticfiles_s3_bucket" {
  region = var.region
  bucket = "integrations-lite-staticfiles"
  acl    = "public-read"

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["PUT", "POST"]
    allowed_origins = ["*"]
    expose_headers  = ["ETag"]
    max_age_seconds = 3000
  }

  website {
    index_document = "index.html"
  }
}

# 创建用于Django上传静态文件的IAM用户
resource "aws_iam_user" "integrations_lite_staticfiles_s3_bucket_user" {
  name = "Integrations-Lite-staticfiles-user"
}

# 生成IAM用户的访问密钥(用于Django配置)
resource "aws_iam_access_key" "integrations_lite_staticfiles_s3_bucket_user_key" {
  user = aws_iam_user.integrations_lite_staticfiles_s3_bucket_user.name
}

# IAM用户的权限策略:遵循最小权限原则,仅授予上传/管理静态文件的必要权限
data "aws_iam_policy_document" "integrations_lite_staticfiles_s3_user_policy" {
  statement {
    effect = "Allow"
    actions = [
      "s3:PutObject",
      "s3:DeleteObject",
      "s3:ListBucket"
    ]
    resources = [
      aws_s3_bucket.integrations_lite_staticfiles_s3_bucket.arn,
      "${aws_s3_bucket.integrations_lite_staticfiles_s3_bucket.arn}/*"
    ]
  }
}

# 将权限策略绑定到IAM用户
resource "aws_iam_user_policy" "integrations_lite_staticfiles_s3_user_policy" {
  name = "Integrations-Lite-staticfiles-user-policy"
  user = aws_iam_user.integrations_lite_staticfiles_s3_bucket_user.name
  policy = data.aws_iam_policy_document.integrations_lite_staticfiles_s3_user_policy.json
}

# S3桶的公开访问策略:允许所有用户GET静态文件
data "aws_iam_policy_document" "integrations_lite_staticfiles_s3_bucket_policy" {
  statement {
    sid       = "PublicReadForGetBucketObjects"
    effect    = "Allow"
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.integrations_lite_staticfiles_s3_bucket.arn}/*"]
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
  }
}

# 将公开访问策略绑定到S3桶
resource "aws_s3_bucket_policy" "integrations_lite_staticfiles_s3_bucket_policy" {
  bucket = aws_s3_bucket.integrations_lite_staticfiles_s3_bucket.id
  policy = data.aws_iam_policy_document.integrations_lite_staticfiles_s3_bucket_policy.json
}

关键修改点说明

  1. 修正桶策略引用:把aws_s3_bucket_policy的policy字段改为引用专门的桶策略文档,确保包含Principal字段。
  2. 细化IAM用户权限:将原来过于宽泛的s3:*权限缩小为仅必要的上传、删除和列桶操作,同时覆盖桶本身和桶内所有对象,遵循最小权限原则。
  3. 修正桶策略资源范围:把桶策略的resources指向桶内所有对象(${arn}/*),因为s3:GetObject是针对对象的操作,不是桶本身。
  4. 升级Terraform语法:移除了过时的${var.xxx}插值语法,改用Terraform 0.12+推荐的直接引用方式。

额外注意事项

  • 执行terraform apply后,记得把生成的aws_iam_access_key的id和secret配置到Django的settings.py中(对应AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY)。
  • 公开S3桶存在安全风险,如果你的静态文件仅需特定域名访问,可以修改桶策略的principals或添加条件限制来源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:23:28