Terraform使用for_each调用模块时如何插值引用data资源名称
实现方案
你原写法中直接在资源引用标识符中插值${each.key}是不合法的,Terraform不支持动态构造资源引用路径,以下是两种可落地的实现方式:
方案1:data块与模块共用for_each(推荐)
适合策略结构相似,可通过动态逻辑生成的场景,新增策略仅需修改变量即可,无需新增冗余代码:
# 定义策略索引变量,key为策略唯一标识 variable "example_policies_mapped_to_roles" { type = map(string) default = { "example-service" = "service-policy" # 新增策略只需在此处加对应键值对即可 } } # data块共用同一个变量做for_each,批量生成所有需要的策略文档 data "aws_iam_policy_document" "policy" { for_each = var.example_policies_mapped_to_roles # 通用策略配置 statement { sid = "AllowListBuckets" actions = ["s3:ListAllMyBuckets"] resources = ["*"] } # 不同key的差异化策略用动态块实现 dynamic "statement" { # 示例:仅example-admin标识的策略加全量S3权限 for_each = each.key == "example-admin" ? [1] : [] content { sid = "AllowFullS3Access" actions = ["s3:*"] resources = ["*"] } } } module "policy_example" { source = "../modules/aws-iam-policy" for_each = var.example_policies_mapped_to_roles name = "example-${each.key}" path = "/" # 直接通过索引取对应策略的json即可 policy = data.aws_iam_policy_document.policy[each.key].json }
方案2:手动构造策略映射表
适合不同策略差异极大,无法统一写生成逻辑的场景:
# 单独定义各个差异化的策略文档 data "aws_iam_policy_document" "policy-example-service" { statement { sid = "AllowListBuckets" actions = ["s3:ListAllMyBuckets"] resources = ["*"] } } data "aws_iam_policy_document" "policy-example-admin" { statement { sid = "AllowFullS3Access" actions = ["s3:*"] resources = ["*"] } } # 手动构造索引映射表,key对应变量中的策略标识,value为对应策略的json locals { policy_json_map = { "example-service" = data.aws_iam_policy_document.policy-example-service.json "example-admin" = data.aws_iam_policy_document.policy-example-admin.json } } module "policy_example" { source = "../modules/aws-iam-policy" for_each = var.example_policies_mapped_to_roles name = "example-${each.key}" path = "/" policy = local.policy_json_map[each.key] }
内容的提问来源于stack exchange,提问作者Howard_Roark
相关产品推荐
相关产品推荐

