Terraform for_each with yaml variable file failing on queue creation

trying to spin up multiple routing queues from a yaml var file using for_each. the terraform docs say “for_each accepts a map or a set of strings and creates an instance for each item.” so i’ve got this block:

resource "genesyscloud_routing_queue" "queues" {
 for_each = yamldecode(file("queues.yaml"))
 name = each.value.name
}

keeps throwing a plan error about invalid value type. yaml file just has a list of maps. not sure why it’s rejecting the decode output.

3 Likes

honestly, terraform state drift is a pain. but if you’re already pulling analytics, just query the api directly. ignore the provider noise.

get the id via curl.
import it.

don’t fight the 409. just…

is the yaml actually a map of objects or just a list? yamldecode returns different types. if it’s a list, for_each will choke. wrap it in a map first. something like for_each = { for i, q in yamldecode(file("queues.yaml")) : q.name => q }. fixes the type mismatch instantly.

The point above is correct about the type mismatch. for_each needs a map or set. lists don’t fly.

but you’ll hit another wall if name isn’t unique across your yaml. terraform uses the map key as the identifier. if you duplicate a name, the plan fails with a duplicate key error.

use a composite key or an index to be safe.

locals {
 queues_map = { for idx, q in yamldecode(file("queues.yaml")) : "${q.name}-${idx}" => q }
}

resource "genesyscloud_routing_queue" "queues" {
 for_each = local.queues_map
 name = each.value.name
}

keeps things idempotent even if names repeat later.

yeah, the type conversion is the main blocker here. yamldecode spits out a list by default, and for_each strictly requires a map or set. wrapping it in a comprehension like { for i, q in yamldecode(file("queues.yaml")) : q.name => q } forces that conversion. just make sure the names are unique keys, otherwise terraform will throw a duplicate key error during the plan phase.

if you’re piping these queues into a monitoring stack, consider adding a description field to store a Datadog dashboard link or a specific tag. it’s not strictly required for the queue to exist, but it helps when you’re tracing metrics back to the resource. name = each.value.name works fine, but keeping that metadata consistent makes the API calls cleaner later on.

2 Likes