Terraform: Support output of dynamic maps

Created on 4 Apr 2017  ยท  6Comments  ยท  Source: hashicorp/terraform

Currently, as implemented in https://github.com/hashicorp/terraform/pull/5841, Terraform can output maps, however the key needs to be a string.

It would be useful to be able to create a map that had dynamic keys and values.

For example,ย given the following code:

output "network_info" {
  value = "${map(
    openstack_networking_network_v2.network.*.name, openstack_networking_subnet_v2.subnet.*.cidr
  )}"
}

This would enable the following output map:

network_info = {
  network_1a_private = 192.168.20.0/24
  network_1a_public = 192.168.10.0/24
}

Currently, this code fails silently. Debug logging shows:

6:52:14 [WARN] Output interpolation "network_info" failed: map: argument 1 represents a key, so it must be a string in:

${map(
openstack_networking_network_v2.network..name, openstack_networking_subnet_v2.subnet..cidr
)}

The only work-around I have been able to come up with soo far is:

output "network_cidrs" {
  value = "${map(
    "names", openstack_networking_network_v2.network.*.name, 
    "cidrs", openstack_networking_subnet_v2.subnet.*.cidr
  )}"
}

Which produces:

network_map = {
  cidrs = [192.168.20.0/24 192.168.10.0/24]
  names = [network_1a_private network_1a_public]
}

However this then requires additional processing upstream...

Terraform Version

Terraform v0.9.2

Affected Resource(s)

Please list the resources as a list, for example:

  • output
core enhancement

Most helpful comment

@apparentlymart

Cheers for the quick response.
How did I miss that gem?! It works!

For everyone else's benefit:

output "network_info" {
  value = "${zipmap(
    openstack_networking_network_v2.network.*.name, openstack_networking_subnet_v2.subnet.*.cidr
  )}"
}

Produces:

network_zip = {
  network_1a_private = 192.168.20.0/24
  network_1a_public = 192.168.10.0/24
  network_1b_private = 192.168.21.0/24
  network_1b_public = 192.168.11.0/24
}

Obviously, that assumes that you've got 2 lists that are identical in size and ordering...

Another scenario I can potentially foresee is requiring a lookup for the value based on the key... Which wouldn't be possible with the zipmap function?

All 6 comments

Hi @fatmcgav!

If I'm understanding your first example correctly, I think you're looking for the zipmap function, which lets you create a map from a list of keys and a list of corresponding values.

@apparentlymart

Cheers for the quick response.
How did I miss that gem?! It works!

For everyone else's benefit:

output "network_info" {
  value = "${zipmap(
    openstack_networking_network_v2.network.*.name, openstack_networking_subnet_v2.subnet.*.cidr
  )}"
}

Produces:

network_zip = {
  network_1a_private = 192.168.20.0/24
  network_1a_public = 192.168.10.0/24
  network_1b_private = 192.168.21.0/24
  network_1b_public = 192.168.11.0/24
}

Obviously, that assumes that you've got 2 lists that are identical in size and ordering...

Another scenario I can potentially foresee is requiring a lookup for the value based on the key... Which wouldn't be possible with the zipmap function?

Indeed, right now Terraform doesn't have support for generic handling of collections such as calling a function for each member of a list, which I think is the building block needed for the use-case you were asking about at the end. This might come as a future enhancement to the configuration language, but at present there is no way to do that.

We will be looking at various improvements to the configuration language in the near future, and the ability to map over list members is something that has come up before and is likely to already be in that discussion, so I'm going to close this out for now since that's beyond the original scope of this ticket and something we'll approach as part of some more holistic language improvements.

No worries, cheers for the info :)

Excellent! If you want to set a static key, but render a zipmap of splat* values to the value array on that key, how would one go about doing that?

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings