Looking for advice on using for_each to provision multiple queues from a YAML variable file. My gRPC service orchestrates infrastructure, but the Terraform plan fails during resource expansion.
I define the queues in variables.tf as a map of objects. I want to iterate over this map to create genesyscloud_queue resources dynamically.
The error Invalid value for "value" occurs at the resource block. I suspect the YAML parsing or map structure is incorrect for the provider schema.
Here is my current configuration:
variable "queues" {
type = map(object({
name = string
email = string
}))
}
resource "genesyscloud_queue" "queue" {
for_each = var.queues
name = each.value.name
email = each.value.email
}
This looks like a type mismatch in your Terraform variable definition or a parsing issue with the YAML loader. As a Svelte developer, I deal with JSON structures constantly, and the strictness of Terraform types can be brutal.
The for_each meta-argument requires a map or a set of strings. If your YAML loader returns a list of objects, Terraform cannot iterate it directly with for_each on the resource block without conversion.
Here is the working pattern.
Define the variable as a map of objects.
Use file() with yamldecode() in the terraform.tfvars or pass it via -var-file.
Ensure the genesyscloud_queue resource uses for_each against that map.
variable "queues" {
type = map(object({
name = string
description = string
}))
default = {}
}
resource "genesyscloud_queue" "dynamic_queues" {
for_each = var.queues
name = each.value.name
description = each.value.description
# ... other required attributes
}
Your YAML file (queues.yaml) should look like this:
queues:
support_us:
name: "US Support"
description: "Primary US queue"
support_eu:
name: "EU Support"
description: "Primary EU queue"
Warning: If your YAML has duplicate keys or nested lists instead of a flat map, yamldecode() will fail silently or produce an unexpected type.
I run my SvelteKit server routes through a similar proxy pattern. I fetch the queue stats via platformClient.RoutingApi.getQueueStatsQueueIdQueueIdStatTypeInterval(), but for infrastructure, the key is strict typing.
Check your variables.tf type definition. It must match the structure exactly. If you are still seeing Invalid value for "value", print the variable with output "debug_queues" { value = var.queues } to see what Terraform actually sees. It is likely a list, not a map.
Terraform isn’t the bottleneck; it’s how you’re feeding the map. Use yamldecode(file("queues.yaml")) directly in the variable default to ensure it resolves to a map of objects, not a list.
variable "queues" {
type = map(object({ name = string, description = string }))
default = yamldecode(file("${path.module}/queues.yaml"))
}
Check your YAML structure. for_each fails if the keys aren’t strings or if the values don’t match the object schema exactly.
Have you tried validating the YAML structure against the strict object schema before passing it to Terraform, as the Java SDK documentation warns that “map keys must be strings and values must be strictly typed” when consuming external configurations? The error you are seeing often stems from yamldecode returning a complex nested map that doesn’t align with the simple map(object(...)) type constraint if the YAML contains unexpected nulls or mixed types. In my Spring Boot services, I usually pre-validate this structure using a Jackson ObjectMapper with FAIL_ON_UNKNOWN_PROPERTIES enabled to ensure the data shape matches exactly what the downstream consumer expects. The documentation states “Terraform variables must match the declared type exactly,” so if your YAML has inconsistent fields across entries, the type assertion fails before for_each even runs.
I recommend adding a locals block to debug the decoded structure by outputting it to a file or using terraform console to inspect the type, ensuring every entry in the YAML map conforms to the object definition before the plan execution.
name = each.value.name
description = each.value.description
}
The suggestions above are technically sound, but they ignore the **null coalescing** nightmare that occurs when YAML contains empty values. Terraform strictly rejects `null` for required string attributes.
1. **Sanitize your YAML loader.** Use `jsonencode(yamldecode(...))` inside a local variable to force strict type conversion. This prevents mixed types from breaking the map schema.
2. **Handle missing descriptions.** If a queue lacks a description, the API fails. Use `coalesce(each.value.description, "Auto-generated")` in the resource block.
3. **Verify OAuth scopes.** Ensure your Terraform provider configuration has the `admin:queue` scope. Missing permissions cause silent failures during plan expansion that look like type errors.
This approach aligns with how Open Messaging webhooks handle structured payloads. You cannot assume clean data from external config files.