如何在Terraform中更高效地实现标签到资源的映射转换?
问题描述
给定Terraform变量var.input_var(结构如下),需要生成一个以所有元素的标签为键,对应资源信息(key和name)列表为值的映射。
变量定义
variable "input_var" = { type = object(map( object({ name = string tags = optional(list(string)) }) )), default = { "one" = { name = "nameone" tags = ["tag1", "tag2"] } "two" = { name = "nametwo" tags = ["tag1", "tag3"] } "three" = { name = "namethree" tags = ["tag2"] } "four" = { name = "namefour" } } }
目标输出
{ "tag1": [ { name = "nameone" key = "one" }, { name = "nametwo" key = "two" }, ], "tag2": [ { name = "nameone" key = "one" }, { name = "namethree" key = "three" } ], "tag3": [ { name = "nametwo" key = "two" } ] }
注:原示例中tag2列表遗漏了one对应的资源,正确输出应包含该条目。
现有两步实现
- 生成唯一标签集合
locals{ tags_set = distinct(flatten([ for k, v in var.input_var: coalesce(v.tags, []) ])) }
- 基于标签集合构建映射
tags_map = { for key_tag in local.tags_set: key_tag => flatten([for k, v in var.input_var: [ for tag in coalesce(v.tags, []) : { key = k name = v.name } if tag == key_tag ]]) }
单步高效优化方案
可以通过嵌套for表达式结合merge函数一步完成,只需要遍历一次var.input_var,性能更优:
locals { tags_map = merge([ for k, v in var.input_var : { for tag in coalesce(v.tags, []) : tag => [{ key = k, name = v.name }] } ]...) }
实现逻辑
- 外层遍历每个资源的键
k和属性v - 内层遍历当前资源的每个标签
tag,生成一个临时小映射:键为标签,值是包含当前资源信息的单元素列表 - 用
merge(...,)把所有临时映射合并,相同标签对应的列表会自动拼接在一起,最终得到目标结构
这个方案无需先生成标签集合,直接一次遍历完成分组,代码更简洁,执行效率也更高。
内容的提问来源于stack exchange,提问作者codiac
相关产品推荐
相关产品推荐

