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

如何在Terraform模块中合并name、public_ip、private_ip输出为单行?

将Terraform模块多输出合并为单行内容的实现方法

问题场景

我在Terraform模块中定义了多个输出,希望将它们合并为类似name + public_ip + private_ip的单行内容,请问是否可行?

现有模块输出定义如下:

output "name" {
  description = "服务器名称列表"
  value       = hcloud_server.this[*].name
}

output "public_ip" {
  description = "实例公网IPv4地址列表"
  value       = hcloud_server.this[*].ipv4_address
}

output "private_ip" {
  description = "实例私网IPv4地址列表"
  value       = flatten(hcloud_server.this[*].network)[*].ip
}

output "id" {
  description = "服务器ID列表"
  value       = hcloud_server.this[*].id
}

output "test" {
  description = "服务器完整信息列表"
  value       = hcloud_server.this[*]
}

我尝试使用merge()函数但未成功。

补充:应用后hcloud_server的输出示例如下:

Outputs:

server = [
  {
    "allow_deprecated_images" = false
    "backup_window" = ""
    "backups" = false
    "datacenter" = "nbg1-dc3"
    "delete_protection" = false
    "firewall_ids" = toset([
      1394082,
    ])
    "id" = "47294153"
    "ignore_remote_firewall_ids" = false
    "image" = "15512617"
    "ipv4_address" = "128.140.107.214"
    "ipv6_address" = ""
    "ipv6_network" = "<nil>"
    "iso" = tostring(null)
    "keep_disk" = false
    "labels" = tomap({
      "pscloud_managed-by-terraform" = "true"
    })
    "location" = "nbg1"
    "name" = "testcustomer.testproject.nbg1-dc3.dev.testserver01"
    "network" = toset([
      {
        "alias_ips" = toset([])
        "ip" = "192.168.1.1"
        "mac_address" = "86:00:00:8a:5c:a8"
        "network_id" = 4233067
      },
    ])
    "placement_group_id" = 341672
    "primary_disk_size" = 20
    "public_net" = toset([
      {
        "ipv4" = 0
        "ipv4_enabled" = true
        "ipv6" = 0
        "ipv6_enabled" = false
      },
    ])
    "rebuild_protection" = false
    "rescue" = tostring(null)
    "server_type" = "cx11"
    "shutdown_before_deletion" = false
    "ssh_keys" = tolist([
      "20782188",
    ])
    "status" = "running"
    "timeouts" = null /* object */
    "user_data" = tostring(null)
  },
]

实现方案

当然可行,merge()函数主要用于合并映射(map)类型数据,而你需要的是将列表中对应位置的元素拼接成字符串,所以得换个思路。

方法1:直接遍历服务器列表生成拼接字符串

利用Terraform的for表达式遍历hcloud_server.this列表,对每个服务器对象直接提取所需字段并拼接:

output "server_summary" {
  description = "单行格式的服务器信息列表"
  value = [
    for server in hcloud_server.this :
    "${server.name} + ${server.ipv4_address} + ${flatten(server.network)[0].ip}"
  ]
}

这里因为server.network是集合类型,先用flatten转成列表,再取第一个元素的ip作为私有IP(适用于每个服务器仅关联一个私有网络的场景)。

方法2:基于现有输出列表拼接

如果要基于已定义的name、public_ip、private_ip输出列表来拼接,可以通过索引遍历实现:

output "server_summary_from_outputs" {
  description = "基于现有输出生成的单行服务器信息"
  value = [
    for idx, name in name :
    "${name} + ${public_ip[idx]} + ${private_ip[idx]}"
  ]
}

注意:这种方法要求三个列表的元素数量和顺序完全对应,否则会出现字段匹配错误。

输出示例

应用后,server_summary的输出会是类似:

[
  "testcustomer.testproject.nbg1-dc3.dev.testserver01 + 128.140.107.214 + 192.168.1.1"
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:49:51