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

如何在Terraform中按环境条件控制S3桶IAM策略语句?

方法1:为单个语句单独使用动态块

针对每个需要环境控制的语句,单独用dynamic "statement"块,通过for_each判断环境条件来决定是否生成该语句。这种方式不需要统一所有语句的结构,每个动态块的内容可以完全独立编写,适配参数差异大的场景。

示例代码:

data "aws_iam_policy_document" "inbound_bucket_policy" { 
  # 始终生成的对象权限语句
  statement {
    sid    = "Set permissions for objects"
    effect = "Allow"
    principals {
      identifiers = [var.inbound_source_replication_role_arn]
      type        = "AWS"
    }
    actions = [
      "s3:ReplicateObject",
      "s3:ReplicateDelete",
      "s3:ReplicateTags"
    ]
    resources = ["${aws_s3_bucket.inbound_bucket.arn}/*"]
  }

  # 仅非生产环境生成的桶权限语句
  dynamic "statement" {
    for_each = var.env != "prd" ? [1] : []
    content {
      sid    = "Set permissions on bucket"
      effect = "Allow"
      principals {
        identifiers = [var.inbound_source_replication_role_arn]
        type        = "AWS"
      }
      actions   = ["s3:List*", "s3:GetBucketVersioning", "s3:PutBucketVersioning"]
      resources = [aws_s3_bucket.inbound_bucket.arn]
    }
  }
}

方法2:用本地变量管理所有语句(适合未来批量新增)

把所有语句的配置和启用条件放到locals里,过滤出符合条件的语句后,再通过动态块批量生成。这种方式便于统一管理所有语句,新增时只需在本地变量数组里添加条目即可。

示例代码:

locals {
  statements = [
    {
      enabled = true # 始终生效
      config = {
        sid    = "Set permissions for objects"
        effect = "Allow"
        principals = {
          identifiers = [var.inbound_source_replication_role_arn]
          type        = "AWS"
        }
        actions = [
          "s3:ReplicateObject",
          "s3:ReplicateDelete",
          "s3:ReplicateTags"
        ]
        resources = ["${aws_s3_bucket.inbound_bucket.arn}/*"]
      }
    },
    {
      enabled = var.env != "prd" # 仅非生产环境生效
      config = {
        sid    = "Set permissions on bucket"
        effect = "Allow"
        principals = {
          identifiers = [var.inbound_source_replication_role_arn]
          type        = "AWS"
        }
        actions   = ["s3:List*", "s3:GetBucketVersioning", "s3:PutBucketVersioning"]
        resources = [aws_s3_bucket.inbound_bucket.arn]
      }
    }
    # 未来新增语句直接在这里添加条目即可
  ]

  # 过滤出需要生效的语句配置
  enabled_statements = [for s in local.statements : s.config if s.enabled]
}

data "aws_iam_policy_document" "inbound_bucket_policy" {
  dynamic "statement" {
    for_each = local.enabled_statements
    content {
      sid    = statement.value.sid
      effect = statement.value.effect

      principals {
        identifiers = statement.value.principals.identifiers
        type        = statement.value.principals.type
      }

      actions   = statement.value.actions
      resources = statement.value.resources
    }
  }
}

方法3:拆分数据源后合并策略

把不同环境的策略拆分成独立的aws_iam_policy_document数据源,再通过source_json和override_json合并最终的策略文档。这种方式适合语句结构差异极大的场景,每个数据源可以完全独立编写逻辑。

示例代码:

# 基础策略:所有环境都生效的语句
data "aws_iam_policy_document" "inbound_bucket_base" {
  statement {
    sid    = "Set permissions for objects"
    effect = "Allow"
    principals {
      identifiers = [var.inbound_source_replication_role_arn]
      type        = "AWS"
    }
    actions = [
      "s3:ReplicateObject",
      "s3:ReplicateDelete",
      "s3:ReplicateTags"
    ]
    resources = ["${aws_s3_bucket.inbound_bucket.arn}/*"]
  }
}

# 非生产专属策略:仅非prd环境生成
data "aws_iam_policy_document" "inbound_bucket_non_prd" {
  count = var.env != "prd" ? 1 : 0
  statement {
    sid    = "Set permissions on bucket"
    effect = "Allow"
    principals {
      identifiers = [var.inbound_source_replication_role_arn]
      type        = "AWS"
    }
    actions   = ["s3:List*", "s3:GetBucketVersioning", "s3:PutBucketVersioning"]
    resources = [aws_s3_bucket.inbound_bucket.arn]
  }
}

# 合并最终策略
data "aws_iam_policy_document" "inbound_bucket_policy" {
  source_json = data.aws_iam_policy_document.inbound_bucket_base.json
  override_json = var.env != "prd" ? data.aws_iam_policy_document.inbound_bucket_non_prd[0].json : "{}"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:43:09