如何为Terraform现有Map条件式添加元素?
Terraform 为Map类型变量添加匹配属性的解决方案
问题背景
现有一个名为tiers的Terraform Map类型变量,定义如下:
variable "tiers" { default = { DEMO_APP = { env = "demo" sg = "tier-f5b5d2b4" } DEMO_DB = { env = "demo" sg = "tier-5425ce73" } DEV_APP = { env = "dev" sg = "tier-8e96a095" } DEV_DB = { env = "dev" sg = "tier-3ac50a95" } QA_APP = { env = "qa" sg = "tier-a176357f" } QA_DB = { env = "qa" sg = "tier-0d05fa93" } } description = "Map of security group IDs" type = map(object({ env = string sg = string })) }
需要为该Map的每个元素添加lb字段,字段值来自以下data对象生成的结果列表:
data "loadbalancer" "lbs" { subproject = subproject.id }
最终每个Map元素需包含额外的lb属性,示例如下:
DEMO_APP = { env = "demo" sg = "tier-f5b5d2b4" lb = "lb-8956l096" }
要求:相同env值的元素必须拥有相同的lb值。
尝试的方案及问题
曾尝试用flatten处理结构,代码如下:
locals { App_LBs = flatten([ for keys, values in var.tiers : { name = keys env = values.env sg = values.sg lb = join("", [ for each in data.loadbalancer.lbs.results : each.id if each.name == "${var.lb_prefix}-${values.env}" ]) } ]) }
预期生成包含多个对象的元组结构,但在使用for_each时失败——因为for_each仅支持映射(map)或集合(set)类型,元组无法直接作为其参数。
最终解决方案
通过映射推导式直接生成符合要求的Map类型结构,代码如下:
tiers_with_load_balancers = { for tier, attributes in var.tiers : tier => merge(attributes, { lb = join("", [ for each in data.loadbalancer.lbs.results : each.id if each.name == "${var.lb_prefix}-${attributes.env}" ]) }) }
该方案的核心逻辑:
- 使用映射推导式保留原
tiers的键名,生成新的Map - 通过
merge函数将原元素属性与新增的lb字段合并 - 内部通过for循环匹配对应
env的负载均衡器ID,确保相同env的元素获取到同一个lb值 - 最终生成的Map可直接用于
for_each参数
内容的提问来源于stack exchange,提问作者Chris Batchelor
相关产品推荐
相关产品推荐

