如何在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
相关产品推荐
相关产品推荐

