Terraform CXone Provider: Queue skill mapping fails with 400 Bad Request

I am trying to automate queue provisioning using the nice_cxone Terraform provider. The goal is to create a queue and assign specific skills to it in a single apply cycle.

I have defined the queue resource and the skill resources separately. The skills are created first, which works fine. The issue arises when I try to reference those skills in the nice_cxone_queue resource using the skills block.

Here is the relevant :

resource "nice_cxone_queue" "support_queue" {
 name = "Tier 1 Support"
 
 skills {
 for_each = var.skill_ids
 name = each.value
 }
}

When I run terraform apply, the provider throws a 400 Bad Request error. The error message is vague:

Error: POST https://api.cxone.com/api/v2/queues returned 400
Body: {"errors":[{"code":"bad_request","message":"Invalid skill configuration"}]}

I verified the skill IDs exist and are active. I also tried using the skill names instead of IDs, but the result is the same. The documentation for the provider is sparse on how to handle dynamic skill assignments.

I checked the raw API request using the Terraform debug logs. The payload sent to the API looks like this:

{
 "name": "Tier 1 Support",
 "skills": [
 {"name": "billing"},
 {"name": "technical"}
 ]
}

If I manually curl this payload to the API, it works. So the structure seems correct. The issue might be with how the provider handles the for_each loop or timing dependencies between the skill creation and queue creation.

Has anyone successfully mapped skills to queues using this provider? I am stuck on why the API rejects the valid-looking payload when called through Terraform. The provider version is 1.2.4. I have tried adding a depends_on clause pointing to the skill resources, but that did not help.

You’re hitting the provider’s internal validation logic. The nice_cxone_queue resource expects the skills block to reference IDs that already exist in the API, but Terraform’s dependency graph can sometimes evaluate the block before the skill resources are fully committed, or the schema expects a specific nested structure that differs from the raw API payload.

Try splitting the configuration. Create the queue first with an empty skills block or omit it entirely. Then use a separate nice_cxone_queue_skill resource (if available in your provider version) or a local-exec with curl to patch the queue after creation.

If you must do it in one resource, ensure your skill IDs are explicitly referenced via output variables, not interpolated strings that might resolve to empty.

resource "nice_cxone_queue" "main" {
 name = "Support"
 # omit skills block initially
}

# Then patch via local-exec if the provider doesn't support post-create skill assignment cleanly
resource "null_resource" "assign_skills" {
 depends_on = [nice_cxone_queue.main, nice_cxone_skill.support]
 
 provisioner "local-exec" {
 command = "curl -X PATCH https://api.mypurecloud.com/api/v2/routing/queues/${nice_cxone_queue.main.id} -H 'Authorization: Bearer ${var.access_token}' -d '{\"skills\": [{\"id\": \"${nice_cxone_skill.support.id}\", \"level\": 5}]}'"
 }
}