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

如何基于YAML构建自定义本地变量适配Terraform for_each循环?

问题描述

我们的环境里有个/apps目录,里面放了多个YAML文件,每个文件定义了应用名称和对应的主机名列表。已经用下面的代码把这些文件加载成了本地变量:

applications = [for filename in fileset(path.module, "apps/*.yml") : yamldecode(file(filename))]

local.applications里存着应用和主机名的结构化数据。现在需要生成一个映射列表,每个映射以主机名(hostname.name)为键、应用名称(name)为值,格式如下:

[
{testing-a: testing one},
{testing-b: testing one},
{testing-x: testing-two}
]

这个列表要用来给Terraform资源的for_each循环用,实现批量创建资源,该怎么实现?

解决方案

生成目标映射列表

假设你的YAML文件结构类似这样(比如testing-one.yml):

name: "testing one"
hostnames:
  - name: "testing-a"
  - name: "testing-b"

另一个testing-two.yml:

name: "testing-two"
hostnames:
  - name: "testing-x"

可以用Terraform的嵌套for表达式结合flatten()函数来生成你要的列表:

locals {
  applications = [for filename in fileset(path.module, "apps/*.yml") : yamldecode(file(filename))]
  
  # 生成目标映射列表
  hostname_to_app = flatten([
    for app in local.applications : [
      for hostname in app.hostnames : {
        "${hostname.name}" = app.name
      }
    ]
  ])
}
  • 内层循环会为每个应用下的主机名生成单独的键值映射,比如{testing-a: "testing one"}
  • 外层循环遍历所有加载的应用,收集每个应用对应的主机名映射列表
  • flatten()函数会把嵌套的列表(比如[[{...}, {...}], [{...}]])转成一维列表,也就是你需要的格式

更适合for_each的优化方案

其实如果是给for_each用,更推荐把它转换成单一的映射(而非列表),因为for_each对映射的支持更友好——每个元素有唯一键,Terraform能更清晰地跟踪资源实例:

locals {
  applications = [for filename in fileset(path.module, "apps/*.yml") : yamldecode(file(filename))]
  
  # 生成单一映射,key为主机名,value为应用名称
  hostname_app_map = merge([
    for app in local.applications : {
      for hostname in app.hostnames : hostname.name => app.name
    }
  ]...)
}

生成的local.hostname_app_map结构是:

{
  "testing-a" = "testing one"
  "testing-b" = "testing one"
  "testing-x" = "testing-two"
}

在资源中使用时:

resource "example_resource" "test" {
  for_each = local.hostname_app_map
  
  name      = each.key   # 主机名
  app_name  = each.value # 应用名称
}

内容的提问来源于stack exchange,提问作者leonms.dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:21:15