terraform multiple value output

Viewed 519

I create multiple Digital Ocean Droplet resource (VM) using Terraform(TF) and set every VM random string password from TF common resource by remote-exec provisioner.

resource "digitalocean_droplet" "testvm" {
  count    = var.count_of_droplets
  image    = "ubuntu-20-04-x64"
  name     = "testvm-${count.index}"
  region   = "nyc3"
  size     = "s-1vcpu-1gb"
  ssh_keys = [data.digitalocean_ssh_keys.keys.ssh_keys[0].id]
  provisioner "remote-exec" {

    connection {
      type        = "ssh"
      user        = "root"
      private_key = file("${var.my_ssh_private_key}")
      host        = self.ipv4_address
    }
    inline = [
      "echo '${var.os_user}:${random_string.password[count.index].result}' | sudo chpasswd",
      "sed -i '/PermitRootLogin/c PermitRootLogin yes' /etc/ssh/sshd_config",
      "systemctl restart sshd"
    ]
  }
  tags = ["dev"]
}

and random password generator:

resource "random_string" "password" {
  count            = var.count_of_droplets
  length           = 16
  special          = true
  override_special = "_%@"
}

I print public ip for every created VM with name of VM by Terraform output:

output "droplet_ip_addresses" {
  value =    {
      for droplet in digitalocean_droplet.testvm :
      droplet.name => droplet.ipv4_address
    }
}

output:

droplet_ip_addresses = {
   - testvm-0 = "1.1.1.1"
   - testvm-1 = "2.2.2.2"
}

How i can add to above output generated password? Like:

droplets_data = {
   - testvm-0 = "1.1.1.1" = "5j1dYBZzqDd30yhJ"
   - testvm-1 = "2.2.2.2" = "6R%wj4zebwd9FiAt"
}
1 Answers

Since resources created via a count generates a list of objects you could use the index of the two resources lists to map them together.

Something like

output "droplets_data" {
  value = {
    for index, droplet in digitalocean_droplet.testvm :
      droplet.name => "'${droplet.ipv4_address}' = '${random_string.password[index].result}'"
  }
}

Will output you something that will look like this:

droplets_data = {
  "testvm-0" = "'1.1.1.1' = 'KIUNOQ9YOtCk2aZQ'"
  "testvm-1" = "'2.2.2.2' = 'aTPOtb4%RCcfNo@R'"
}

Something probably cleaner, though, would be to create objects with an ip and a password properties.

Something like:

output "droplets_data" {
  value = {
    for index, droplet in digitalocean_droplet.testvm :
      droplet.name => {
        ip = droplet.ipv4_address
        password = random_string.password[index].result
      }
  }
}

That will yield:

droplets_data = {
  "testvm-0" = {
    "ip" = "1.1.1.1"
    "password" = "KIUNOQ9YOtCk2aZQ"
  }
  "testvm-1" = {
    "ip" = "2.2.2.2"
    "password" = "aTPOtb4%RCcfNo@R"
  }
}
Related