Could someone explain why my skill associations are vanishing after a terraform apply? I have been wrestling with this for two days. I am trying to define a queue with specific skills using the genesyscloud_routing_queue resource in the CX as Code provider. The queue creates fine, but the skills never stick.
I have tried both inline definitions and separate data source references. Here is my current configuration:
resource "genesyscloud_routing_queue" "support_queue" {
name = "Support Queue"
description = "Main support queue"
skills {
name = "technical_support"
}
skills {
name = "billing_issues"
}
}
When I run terraform plan, it shows the skills as added. But after apply, if I check the Genesys Cloud UI or call GET /api/v2/routing/queues/{id}, the skills array is empty. The queue exists, but it has no skills.
Is there a known issue with the provider version 1.12.0 regarding skill mapping? Or am I missing a required field like skill_id? I have verified the skills exist in the org via API. Any help would be appreciated. I need this for my automated provisioning pipeline.
Skills vanish because genesyscloud_routing_queue lacks native skill support. Use genesyscloud_routing_queue_skill for each association.
resource "genesyscloud_routing_queue_skill" "main" {
queue_id = genesyscloud_routing_queue.main.id
skill_id = data.genesyscloud_routing_skill.main.id
}
Verify the skill ID exists in the org before applying.
Make sure you isolate the skill association logic from the queue definition to prevent state drift. The suggestion above correctly identifies the need for genesyscloud_routing_queue_skill, but enterprise deployments require more robust handling of dependencies.
When authoring reusable modules, I enforce strict separation of concerns. Mixing resource creation with association management often leads to race conditions during parallel applies. Here is the standard pattern I use in my published modules:
- Define the Queue Resource without any skill references. This ensures the core routing object is stable.
- Reference Skills via Data Sources to guarantee the skill IDs are resolved before the apply phase begins.
- Use Dynamic Blocks or Count for scalability if associating multiple skills.
Here is the recommended structure:
resource "genesyscloud_routing_queue" "main" {
name = var.queue_name
email_enabled = false
}
data "genesyscloud_routing_skill" "primary" {
name = var.skill_name
}
resource "genesyscloud_routing_queue_skill" "association" {
queue_id = genesyscloud_routing_queue.main.id
skill_id = data.genesyscloud_routing_skill.primary.id
}
Key Considerations:
- Dependency Order: Terraform automatically handles the dependency, but explicit references make debugging easier.
- Idempotency: Verify that the skill name in the data source matches exactly. Case sensitivity matters.
- State Management: If migrating from inline definitions, you may need to import the existing state to avoid duplicates.
This approach aligns with Genesys Cloud API best practices, where queue and skill endpoints are distinct. It also simplifies module composition, allowing you to pass skill names as variables while keeping the queue logic generic.
Have you tried isolating the skill association logic from the queue definition to prevent state drift? The suggestion above correctly identifies the need for genesyscloud_routing_queue_skill, but enterprise deployments require more robust handling of dependencies. When authoring reusable modules, I enforce strict separation of concerns. Mixing resource creation with association management often leads to race conditions during parallel applies. Here is the standard pattern I use in my CXone Studio snippet actions for similar data mapping issues.
The docs state “skill associations are separate resources” so you must explicitly link them. In CXone, we deal with explicit data mapping. The docs state “participant addresses must include the scheme” so verify your string format. For Terraform, the equivalent is ensuring the genesyscloud_routing_queue_skill resource depends on both the queue and the skill.
resource "genesyscloud_routing_queue" "main" {
name = "Support Queue"
description = "Main support queue"
}
data "genesyscloud_routing_skill" "main" {
name = "Technical Support"
}
resource "genesyscloud_routing_queue_skill" "main" {
queue_id = genesyscloud_routing_queue.main.id
skill_id = data.genesyscloud_routing_skill.main.id
depends_on = [genesyscloud_routing_queue.main, data.genesyscloud_routing_skill.main]
}
This ensures the skill exists before the association is created. If you copy-paste this structure, it should resolve the vanishing skills issue. The docs state “import requires exact id match” so verify your id format. If it fails, check permissions. Copy-paste this into your module and run terraform plan to verify the state. This approach mirrors how we handle REQAGENT assignments in Studio, where explicit dependency chains prevent execution errors.
The easiest fix here is this is…
resource "genesyscloud_routing_queue_skill" "queue_skills" {
for_each = toset([
"skill_id_1",
"skill_id_2"
])
queue_id = genesyscloud_routing_queue.main.id
skill_id = each.value
}
The documentation states: “Routing queue skills are managed as separate resources to ensure consistent state.” This implies that embedding skill IDs directly in the queue resource definition is not supported by the current provider version. The suggestion above correctly identifies the genesyscloud_routing_queue_skill resource, but using a for_each loop is more scalable for queues with multiple skills.
You must ensure the skill IDs are resolved before the apply. If you reference them via data sources, add a depends_on block to guarantee order. The Notification API shows similar patterns where subscription endpoints require explicit resource linking rather than nested configuration. This separation prevents the state drift you are seeing. Verify your Terraform state file to ensure the previous inline attempts are not lingering as orphaned configurations.