map list of maps to a list of selected field values in terraform

Uwe Krüger picture Uwe Krüger · May 10, 2017 · Viewed 19k times · Source

If resources use a count parameter to specify multi resources in terraform there is a simple syntax for providing a list/array of dedicated fields for the resource instances.

for example

aws_subnet.foo.*.id

Since quite a number of versions it is possible to declare variables with a complex structure, for example lists of maps.

variable "data" {
  type = "list"
  default = [
    {
      id = "1"
      ...
    },
    {
      id = "10"
      ...
    }
  ]
}

I'm looking for a possibility to do the same for varaibles I can do for multi resources: a projection of an array to an array of field values of the array elements.

Unfortunately

var.data.*.id

does not work as for resources. Is there any possibility to do this?

Answer

Bruce picture Bruce · Oct 27, 2017

UPDATE

Massive fancy features have been added into terraform since Terraform 0.12 was released, e.g., list comprehension, with which the solution is super easy.

locals {
  ids = [for d in var.data: d.id]
  #ids = [for d in var.data: d["id"]]  #same
}

# Then you could get the elements this way,
#     local.ids[0]

Solution before terraform 0.12

template_file can help you out.

data "template_file" "data_id" {
  count = "${length(var.data)}"
  template = "${lookup(var.data[count.index], "id")}"
}

Then you get a list "${data.template_file.data_id.*.rendered}", whose elements are value of "id".

You can get its element by index like this

"${data.template_file.data_id.*.rendered[0]}"

or through function element()

"${element(data.template_file.data_id.*.rendered, 0)}"