如何在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
相关产品推荐
相关产品推荐

