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

Terraform:如何基于匹配属性合并两个映射生成新对象?

Terraform:基于Location匹配合并两个映射生成新对象

目标

基于两个映射的相同location属性匹配创建新对象/映射,最终为多个分支/工作负载NSG部署azurerm_network_watcher_flow_log资源(例如8个分支NSG对应分属westeurope和eastus2的2个Network Watcher)。

背景说明

代码通过for_each遍历包含Azure多资源部署数据的变量var.spokes,其输出结构如下:

+ customerA = {
    + environment = "D"
    + location    = "westeurope"
    + name        = "customerA"
}
+ customerB = {
    + environment = "D"
    + location    = "westeurope"
    + name        = "customerB"
}
+ customerC = {
    + environment = "D"
    + location    = "eastus2"
    + name        = "customerC"
}

需要将var.spokes与数据源data.azurerm_network_watcher.nw按location属性匹配,该数据源输出结构如下:

+ eastus2    = {
    + location            = "eastus2"
    + name                = "NetworkWatcher_eastus2"
    + resource_group_name = "NetworkWatcherRG"
    + tags                = {}
    + timeouts            = null
}
+ westeurope = {
    + location            = "westeurope"
    + name                = "NetworkWatcher_westeurope"
    + resource_group_name = "NetworkWatcherRG"
    + tags                = {}
    + timeouts            = null
}

前提/约束

  • 最终对象/映射需保留var.spokes的键(customerA、customerB等)作为主键;
  • 仅通过两个源映射共有的location属性进行匹配。

预期输出

期望生成如下格式的新对象映射:

+ customerA = {
    + environment                 = "D"
    + location                    = "westeurope"
    + name                        = "customerA"
    + watcher_name                = "NetworkWatcher_westeurope"
    + watcher_resource_group_name = "NetworkWatcherRG"
}
+ customerB = {
    + environment                 = "D"
    + location                    = "westeurope"
    + name                        = "customerB"
    + watcher_name                = "NetworkWatcher_westeurope"
    + watcher_resource_group_name = "NetworkWatcherRG"
}
+ customerC = {
    + environment                 = "D"
    + location                    = "eastus2"
    + name                        = "customerC"
    + watcher_name                = "NetworkWatcher_eastus2"
    + watcher_resource_group_name = "NetworkWatcherRG"
}

已尝试的方法及问题

  1. 第一种方法生成含额外键的异常结果:
locals {
  spoke_nwatchers = {
    for k, v in var.spokes : k => {
      for i, n in values(data.azurerm_network_watcher.nw)[*] : i => {
        watcher_id                  = n.id,
        watcher_name                = n.name,
        watcher_resource_group_name = n.resource_group_name,
        watcher_location            = n.location
        environment                 = v.environment
      } if v.location == n.location
    }
  }
}

output "spoke_nwatchers" {
  value = local.spoke_nwatchers
}
  1. 第二种方法得到包含单个元素的元组而非映射:
locals {
  spoke_nwatchers = {
    for k, v in var.spokes : k => [
      for i, n in data.azurerm_network_watcher.nw : {
        watcher_id                  = n.id,
        watcher_name                = n.name,
        watcher_resource_group_name = n.resource_group_name,
        watcher_location            = n.location,
        environment                 = v.environment
      } if v.location == n.location
    ]
  }
}

解决方案

利用data.azurerm_network_watcher.nw的键与location值一致的特性,直接通过v.location索引对应区域的Network Watcher,再用merge函数合并两个对象的属性,同时给Network Watcher的属性添加前缀避免冲突:

locals {
  spoke_nwatchers = {
    for k, v in var.spokes : k => merge(
      v,
      {
        watcher_name                = data.azurerm_network_watcher.nw[v.location].name
        watcher_resource_group_name = data.azurerm_network_watcher.nw[v.location].resource_group_name
      }
    )
  }
}

output "spoke_nwatchers" {
  value = local.spoke_nwatchers
}

可选:添加存在性校验

如果需要过滤掉没有对应Network Watcher的分支(避免因location不匹配报错),可以添加if条件:

locals {
  spoke_nwatchers = {
    for k, v in var.spokes : k => merge(
      v,
      {
        watcher_name                = data.azurerm_network_watcher.nw[v.location].name
        watcher_resource_group_name = data.azurerm_network_watcher.nw[v.location].resource_group_name
      }
    ) if contains(keys(data.azurerm_network_watcher.nw), v.location)
  }
}

内容的提问来源于stack exchange,提问作者falken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:54:54