You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:45:14