Flatten nested foreach loops with Terraform
12 Sep 2024 in TIL
Given a list of identifiers and an associated list of values, here's how to flatten them all down to a single list of unique values.
hcl
# Define your input data. We'll convert this in to a list of ${name}-${version} valuesvariable "ai_providers" {type = list(object({name = stringversions = list(string)}))default = [{name = "OpenAI"versions = ["gpt-3.5-turbo", "gpt-4o"]},{name = "Anthropic"versions = ["Opus", "Sonnet", "Haiku"]},{name = "Mistral"versions = ["7B", "8x7B", "8x22B"]},{name = "llama3"versions = ["8B", "70B"]},]}## Flatmap using nested loops and flatten()locals {ai_providers_flattened = flatten([for provider in var.ai_providers : [for version in provider.versions : {version = versionprovider = providerkey = "${provider.name}-${version}"}]])}# Iterate over the flattened list to create resourcesresource "demo_foo" "my_resource" {for_each = { for api in local.ai_providers_flattened : api.key => api }name = each.value.providerversion = each.value.version}
The for_each = { for api in local.ai_providers_flattened : api.key => api }
line confused me for a while. This line is used to identify the resource later as my_resource
is now a map of objects rather than a single object. Let's walk through it step by step
demo_foo.my_resource
is a map of objectsdemo_foo.my_resource[api.key]
points to a single resourceapi.key
is defined as"${provider.name}-${version}"
- Details for the
demo_foo
resource for OpenAI gpt-4o is available atdemo_foo.my_resource["OpenAI-gpt-4o"]