Terraform:合并列表生成含重复键的Map及解决merge去重问题
Terraform生成domain与feedback全组合并用于for_each的解决办法
问题根源
你用merge加嵌套for表达式时出现键被覆盖,是因为Terraform的映射(Map)本身不允许重复键,merge遇到重复键只会保留最后一个值。而且for_each要求遍历的集合里每个元素必须有唯一标识,所以直接用domain当键根本走不通。
正确实现:用复合键生成唯一映射
直接生成一个以"域名-反馈值"为唯一键的映射,每个键对应包含原始domain和feedback的对象,这样所有组合都能保留,还满足for_each的唯一性要求。
完整代码示例
variable "domain" { type = list(string) default = ["dom1", "dom2"] } variable "feedback" { type = list(string) default = ["one", "two"] } locals { # 生成所有domain和feedback的组合,用复合键确保唯一 domain_feedback_pairs = { for d in var.domain : for f in var.feedback : "${d}-${f}" => { domain = d feedback = f } } } # 用这个映射来做for_each resource "your_resource" "example" { for_each = local.domain_feedback_pairs # 直接引用每个组合的属性 domain = each.value.domain feedback = each.value.feedback }
生成的结构示例
最终local.domain_feedback_pairs会是这样的,每个键都是唯一的:
{ "dom1-one" = { domain = "dom1", feedback = "one" } "dom1-two" = { domain = "dom1", feedback = "two" } "dom2-one" = { domain = "dom2", feedback = "one" } "dom2-two" = { domain = "dom2", feedback = "two" } }
另一种思路:用对象集合
如果你更喜欢列表结构,可以先生成包含唯一ID的对象列表,再转成集合给for_each用:
locals { domain_feedback_list = flatten([ for d in var.domain : [ for f in var.feedback : { id = "${d}-${f}" domain = d feedback = f } ] ]) # 转成集合,满足for_each的要求 domain_feedback_set = toset(local.domain_feedback_list) } resource "your_resource" "example" { for_each = local.domain_feedback_set domain = each.value.domain feedback = each.value.feedback }
重要提醒
Terraform从设计上就不允许映射有重复键,所以别想着保留重复键,用复合键或唯一ID来区分每个组合才是正道,这也完全符合for_each的使用规则。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

