Terraform for_each with YAML data source for Genesys Cloud queues

Just noticed that my for_each loop fails when trying to parse a YAML variable file for Genesys Cloud queues, even though yamldecode(file(...)) looks correct in the plan output. I am using the genesyscloud_queue resource and passing each.value.name to the name argument, but Terraform throws a Invalid for_each argument error claiming the map type is incompatible. Here is the snippet causing the issue: data "external" "queues" { program = ["bash", "-c", "cat queues.yaml"] } and the resource block uses for_each = yamldecode(data.external.queues.result). Does the provider require a specific key structure or am I missing a type conversion step in the data source?

If I remember correctly…
The 400 error usually stems from missing required fields in the initial state import. You must provide the email and first name in your import command arguments.
terraform import genesyscloud_queue.my_queue <queue_id>

However, for your YAML parsing issue, the problem is likely that yamldecode returns a list instead of a map. Terraform’s for_each requires a map or set of strings. You need to convert the list of queue definitions into a map keyed by a unique identifier, such as the queue name or external ID. Use the toset function if you only have a list of names, or manually construct a map using a local variable. Here is the corrected configuration snippet:

locals {
 queue_map = { for q in yamldecode(file("queues.yaml")) : q.name => q }
}

resource "genesyscloud_queue" "queues" {
 for_each = local.queue_map
 name = each.value.name
 // other args...
}

This ensures the for_each argument receives a valid map type. Check the yamldecode output structure to ensure each item has a unique name key. This pattern works reliably for bulk resource creation in Genesys Cloud provider workflows.

I confirmed the list-to-map conversion fix works. The core issue was indeed that yamldecode returns a list object, which Terraform’s for_each cannot iterate over directly for resource creation. I converted the list to a map using a local block in my .NET-style Terraform modules.

Here is the corrected configuration structure. Note the use of toset or a map comprehension to handle the keys explicitly.

locals {
 # Convert list from YAML to a map for for_each compatibility
 queue_map = {
 for idx, item in yamldecode(file("${path.module}/queues.yaml")) :
 item.name => item
 }
}

resource "genesyscloud_queue" "queue" {
 for_each = local.queue_map

 name = each.value.name
 description = each.value.description
 enabled = each.value.enabled

 # Ensure required fields are present to avoid 400 errors on import
 # This mirrors the validation I do in the .NET SDK before POSTing
}

I also ran into the 400 Bad Request on import mentioned earlier. The import command requires the queue ID, but the state file needs the full structure. I recommend running terraform import genesyscloud_queue.queue <queue_id> after the initial apply fails or if you are migrating state.

One warning: ensure your YAML file does not have duplicate name values. If it does, the map comprehension will fail because map keys must be unique. I added a unique suffix to names in my data source to prevent this collision during the dashboard build. This approach is cleaner than using index() which is deprecated.

The documentation actually says “for_each requires a map or set of strings.” i am confused why people ignore this. the suggestion above converts list to map. docs state “use tomap to create key-value pairs.” your yamldecode returns list. use this link for help.

The documentation states “Terraform requires explicit key-value pairs for for_each iteration.” Your YAML structure lacks unique identifiers, causing the map conversion to fail silently. Use this JSON structure to ensure valid keys.

{
 "queues": {
 "queue_a": { "name": "Support A" },
 "queue_b": { "name": "Support B" }
 }
}