Alexander Trauzzi
Alexander Trauzzi

Reputation: 7396

How do I get a list from a for expression in Terraform?

According to the documentation, Terraform for expressions can produce either maps or tuples.

However I end up with the following when I try to use the value in a for_each:

flatten([ for service in var.services: service.subdomains ])
# or
flatten(tolist([ for service in var.services: service.subdomains ]))
# or
tolist(flatten([ for service in var.services: service.subdomains ]))
The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type list of tuple.

The value for services is as follows:

  [
    {
      name = "some-name",
      backend = module.some_module.some_resource,
      subdomains = [
        "subdomainone",
        "subdomaintwo",
      ],
    },
  ]

Here is a minimal repro:

locals {
  services = [
    {
      name = "some-name",
      subdomains = [
        "subdomainone",
        "subdomaintwo",
      ],
    },
  ]
}

resource local_file "whatever" {

  for_each = setproduct([ "one" ], flatten([ for service in local.services: service.subdomains ]))

  filename = "whatever"
}

output services {
  value = local.services
}

output flatten {
  value = flatten([ for service in local.services: service.subdomains ])
}

output setproduct {
  value = setproduct([ "one" ], flatten([ for service in local.services: service.subdomains ]))
}


Is there any way in Terraform to convert a tuple to a list?

(Sidenote: It seems strange that Terraform wouldn't return a list from a for expression instead of a tuple...)

Upvotes: 1

Views: 11415

Answers (1)

Dan Monego
Dan Monego

Reputation: 10087

for_each only works on sets and maps.

It looks subdomains is a tuple, so flatten isn't fully flattening your list. I don't know where var.services is coming from - it may be possible to make subdomains have the type list with a type definition. If not, you could do this:

toset(flatten([ for service in var.services: tolist(service.subdomains) ]))

Upvotes: 1

Related Questions