在Terraform中使用for_each时如何获取索引遍历嵌套对象
解决Terraform中for_each遍历Map内列表对象的问题
问题场景
现有如下Terraform本地变量定义,通过flatten处理得到sdlc_config后生成config_map:
locals { environments = { test-env = { configurations = [ { account_id = "123456789" account_name = "account-name-1" team = "team-1" alias = "us-east" }, { account_id = "123456789" account_name = "account-name-1" team = "team-1" alias = "us-west" }, { account_id = "987654321" account_name = "account-name-2" team = "team-1" alias = "us-east-account-2" }, { account_id = "987654321" account_name = "account-name-2" team = "team-1" alias = "us-west-account" } ] } } } locals { sdlc_config = flatten([ for name, metadata in local.environments : [ for config in metadata.configurations : { name = name account_id = config.account_id account_name = config.account_name team = config.team } ] ]) config_map = { for each in distinct(local.sdlc_config) : "${each.name}" => { config_name = "${each.account_name}-${each.team}-${each.account_id}" }... }
config_map的输出结构为:
{ "test-env" = [ { "config_name" = "account-name-1-team-1-123456789" }, { "config_name" = "account-name-2-team-1-987654321" }, ] }
尝试在data块中用for_each遍历local.config_map时,因每个value是列表对象,无法直接通过索引引用config_name,当前写法不生效:
data "configuration" "configurations" { for_each = local.config_map name = each.value[index].config_name }
解决方案
方法一:重构config_map为扁平可遍历结构
直接调整config_map的生成逻辑,将每个配置项作为独立的map元素,使用唯一组合键作为key,这样for_each可以直接遍历每个配置项:
locals { config_map = { for item in distinct(local.sdlc_config) : "${item.name}:${item.account_name}-${item.team}-${item.account_id}" => { config_name = "${item.account_name}-${item.team}-${item.account_id}" } } } data "configuration" "configurations" { for_each = local.config_map name = each.value.config_name }
这种方式生成的config_map是扁平结构,每个key唯一标识一个配置项,for_each可以直接遍历每个元素,无需处理索引。
方法二:基于现有config_map生成扁平遍历集合
如果需要保留原config_map的结构,可以先将其扁平化,生成包含所有配置项的集合,再用于for_each:
locals { flattened_configs = flatten([ for env_name, config_list in local.config_map : [ for idx, config in config_list : { unique_key = "${env_name}-${idx}" config_name = config.config_name } ] ]) # 转换为map用于for_each config_for_each = { for item in local.flattened_configs : item.unique_key => item } } data "configuration" "configurations" { for_each = local.config_for_each name = each.value.config_name }
这里通过flatten将config_map中每个列表的元素拆出,用env_name+索引生成唯一key,再转换为map后供for_each使用,确保每个遍历项唯一且可直接访问config_name。
内容的提问来源于stack exchange,提问作者Gary Toms
相关产品推荐
相关产品推荐

