Terraform: get outputs with modules and for_each

Viewed 4585

I am using the following version of terraform:

root@sflowc01:~/terraform_proj# terraform version
Terraform v0.14.2
+ provider registry.terraform.io/dmacvicar/libvirt v0.6.2
+ provider registry.terraform.io/hashicorp/template v2.2.0

Within my module (./modules/singlevm/main.tf) , I have defined output as:

output "ips" {
  value = libvirt_domain.db1.network_interface.0.addresses
}

When I run this module in standalone mode, i get the output as a list, like this: (which is as expected)

ips = tolist([
  "192.168.122.167",
])

My tfvars is defined as:

myvms = {
  vm1 = {
    hostname  = "centos01"
    osdisk_gb = 20
    CPU_Count = 4
    RAM       = 256
    Image     = "CentOS-7-x86_64-GenericCloud.qcow2"
  }
  vm2 = {
    hostname  = "ubuntu01"
    osdisk_gb = 40
    CPU_Count = 8
    RAM       = 512
    Image     = "ubuntu-16.04-server-cloudimg-amd64-disk1.img"

  }
}

In my root module, I am creating multiple VMs using for_each, and I am trying to capture the same output from my root module (./main.tf)

module "kvm_instances" {
  source = "./modules/singlevm"
  for_each = var.myvms
  ...
}

output "all_ips" {
  value = ["${module.kvm_instances.*.ips}"]
 }

I get an error

Error: Unsupported attribute

  on main.tf line 23, in output "all_ips":
  23:   value = ["${module.kvm_instances.*.ips}"]
  This object does not have an attribute named "ips". 

So how do I properly extract the IP addresses of all VMs from my root module? Thanks in Advance!

1 Answers

Probably the cleanest object to construct from the output will be a map(list) with the VMs as the keys and their list of IPs as the value. You can use a for expression like the following to construct this map:

output "all_ips" {
  value = { for vm in keys(var.myvms) : vm => module.kvm_instances[vm].ips }
}

which will return a map where each VM is a key and its associated list of output IP addresses according to your output will be the value.

Related