Quick question about using for_each in Terraform to provision multiple Genesys Cloud queues from a YAML variable file.
I am trying to avoid hardcoding queue names by using a local YAML file and the yamldecode function. I want to iterate over the keys to create genesyscloud_routing_queue resources.
My current setup:
data "local_file" "queue_config" {
filename = "${path.module}/queues.yaml"
}
locals {
queue_data = yamldecode(data.local_file.queue_config.content)
}
resource "genesyscloud_routing_queue" "queues" {
for_each = local.queue_data
name = each.key
# ... other config
}
The YAML looks like this:
sales_queue:
description: "Sales team"
support_queue:
description: "Support team"
When I run terraform plan, I get this error:
Invalid function argument: Argument must be a map or object. The result of a call to function yamldecode is a list, not a map.
I thought YAML key-value pairs would map to a Terraform map. Am I structuring the YAML wrong or is there a different way to parse this for for_each? I am stuck on this syntax issue.
Check your yamldecode output structure. Iterating over keys directly often fails if the values are complex objects. Use for expressions to flatten the map into a format compatible with for_each.
locals {
queues = { for k, v in yamldecode(file("${path.module}/queues.yaml")) : k => v }
}
resource "genesyscloud_routing_queue" "main" {
for_each = local.queues
name = each.key
}
This ensures state tracking matches your YAML keys precisely.
The root cause here is the fact that yamldecode returns a map where values are often nested objects, and passing that directly to for_each without explicit flattening or key extraction leads to type mismatch errors in the Genesys Cloud provider. The suggestion above using for expressions is correct, but you need to ensure the keys are unique strings and the values are properly typed for the genesyscloud_routing_queue resource arguments.
The official documentation states: “The for_each argument accepts a map or set of strings. If a map is provided, Terraform will create one instance for each element in the map, using the map key as the instance key.” This means your local variable must strictly output a map of string to object. If your YAML contains complex nested structures like wrap_up_code or outbound_settings, you must map them explicitly.
Here is the working configuration I use in my Spring Boot infrastructure deployment scripts to avoid these issues:
locals {
# Flatten and ensure keys are strings
queue_map = { for k, v in yamldecode(file("${path.module}/queues.yaml")) : k => {
name = v.name
description = v.description
enabled = v.enabled
} if v.enabled == true }
}
resource "genesyscloud_routing_queue" "dynamic_queues" {
for_each = local.queue_map
name = each.value.name
description = each.value.description
enabled = each.value.enabled
# Add other required attributes here
queue_flow_type = "MANUAL"
}
I always validate the yamldecode output by adding an output block in my local dev environment to inspect the structure before applying. This prevents the “inconsistent attributes” error during plan. Also, ensure your queues.yaml does not contain duplicate keys, as Terraform will fail immediately.