Search code examples
terraform

Combine terraform output


I have defined several outputs in my terraform module and want to merge them when to have something like name + public_ip + private_ip in one line. Is this possible?

My module outputs:

output "name" {
  description = "List with names of the servers"
  value       = hcloud_server.this[*].name
}

output "public_ip" {
  description = "List with public IPv4 IPs of the instances"
  value       = hcloud_server.this[*].ipv4_address
}

output "private_ip" {
  description = "List with public IPv4 IPs of the instances"
  value       = flatten(hcloud_server.this[*].network)[*].ip
}

output "id" {
  description = "List with IDs of the servers"
  value       = hcloud_server.this[*].id
}

output "test" {
  description = "List with public IPv4 IPs of the instances"
  value       = hcloud_server.this[*]
}

I tried around with merge() but I didnt get it working

Edit:

The output of hcloud.server looks like this after applied. I need to write something becaue stackoverflow says it looks like there is too much code

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)
  },
]

Solution

  • I created a variable hcloud_server to simulate your list ...

    Below is the sample code

    variable "hcloud_server" {
      type = object({
        this = list(object({
          name = string
          ipv4 = string
          network = set(object({
            ip = string
          }))
        }))
      })
      default = {
        this : [
          { name : "a", ipv4 : "10.0.0.1", network: [{ip : "10.0.1.11"}] },
          { name : "b", ipv4 : "10.0.0.2", network: [{ip : "10.0.2.22"}] },
          { name : "c", ipv4 : "10.0.0.3", network: [{ip : "10.0.3.33"}] },
        ]
      }
    }
    
    output "name" {
      description = "List with names of the servers"
      value       = var.hcloud_server.this[*].name
    }
    
    output "test" {
      value = [
        for x in var.hcloud_server.this :
        "${x.name} + ${x.ipv4} + ${tolist(x.network)[0].ip}"
      ]
    }
    
    

    if we run a terraform plan on that we will get:

    Changes to Outputs:
      + name = [
          + "a",
          + "b",
          + "c",
        ]
      + test = [
          + "a + 10.0.0.1 + 10.0.1.11",
          + "b + 10.0.0.2 + 10.0.2.22",
          + "c + 10.0.0.3 + 10.0.3.33",
        ]
    

    The important part here is:

    for x in var.hcloud_server.this :
    "${x.name} + ${x.ipv4} + ${tolist(x.network)[0].ip}"
    

    We have a simple for loop and just a string interpolation adding what we need