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

如何为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}"
      ])
    })
  }

该方案的核心逻辑:

  1. 使用映射推导式保留原tiers的键名,生成新的Map
  2. 通过merge函数将原元素属性与新增的lb字段合并
  3. 内部通过for循环匹配对应env的负载均衡器ID,确保相同env的元素获取到同一个lb值
  4. 最终生成的Map可直接用于for_each参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:22:17