CX as Code: Defining queue skills with OTel tracing context in Terraform

I’m trying to instrument our Genesys Cloud queue provisioning pipeline with OpenTelemetry. The goal is to capture the Terraform execution trace and link it to the specific genesyscloud_routing_queue resources being created.

Here’s the issue. When I define skills inside the genesyscloud_routing_queue block in my Terraform module, the CX as Code provider throws a validation error on apply. It seems the provider doesn’t like the nested skill block structure I’m using, or maybe I’m missing a reference ID.

resource "genesyscloud_routing_queue" "support_queue" {
 name = "Support Queue - OTel Test"
 description = "Queue for tracing validation"
 
 # This part is failing
 skills {
 skill_id = genesyscloud_routing_skill.general_skill.id
 level = 5
 }
 
 wrap_up_code = genesyscloud_routing_wrapupcode.default_code.wrap_up_code
}

The error message is:

Error: expected skills.0.skill_id to be a string, got number

Wait, that doesn’t make sense. skill_id is definitely a string UUID. I checked the output of the genesyscloud_routing_skill resource. It looks valid.

Is there a specific way the CX as Code provider expects skills to be defined? I’ve been looking at the Terraform registry docs, but they don’t show a clear example of injecting skills with dynamic IDs while maintaining traceability. I need to ensure the skill_id is resolved before the queue resource is applied so my OTel span can capture the dependency graph correctly.

Also, I’m running this in Asia/Manila timezone, so any rate limiting issues might be affecting the state refresh. But the error seems structural.

Anyone else hit this with the CX as Code provider? I’m using version 1.2.4 of the provider.

Here’s the relevant part of my terraform plan output showing the skill ID is correct:

 + resource "genesyscloud_routing_skill" "general_skill" {
 + id = (known after apply)
 + name = "General Support"
 }

The UUID is generated correctly. Why does the provider think it’s a number? I’ve tried casting it to string explicitly but that breaks the plan phase entirely.

I’ve also tried using a local variable to hold the skill ID, but same result. The validation error persists.

Is there a workaround or a specific syntax I’m missing for the skills block? I need to get this working to complete the trace context injection for our deployment pipeline.

I can share the full HCL file if needed, but it’s pretty standard. Just the skills block is causing the headache.

Any ideas?

The validation error you’re seeing is a classic case of the CX as Code provider being stricter than the underlying API. When you nest skills directly inside the genesyscloud_routing_queue block, the provider expects a very specific schema that often clashes with how OpenTelemetry instrumentation hooks into the resource lifecycle. The provider tries to validate the entire nested object before sending it, and if your tracing context is injecting extra metadata or altering the payload structure slightly, it fails.

Here’s what works reliably. You should define skills as separate genesyscloud_routing_skill resources and then reference them in the queue using their IDs. This decouples the skill creation from the queue creation, allowing your OTel traces to capture each step distinctly without the provider choking on complex nested objects.

resource "genesyscloud_routing_skill" "support_skill" {
 name = "Support Level 1"
 description = "L1 Support"
}

resource "genesyscloud_routing_queue" "main_queue" {
 name = "Main Support Queue"

 member_settings {
 enabled = true
 auto_accept = false
 alerting_time_multiplier = 1.0
 }

 # Reference the skill by ID instead of nesting
 skill_ids = [genesyscloud_routing_skill.support_skill.id]
}

This approach also makes your OTel traces cleaner. You get a distinct span for the skill creation and another for the queue update. The provider doesn’t have to serialize a massive nested object, which reduces the chance of those weird validation errors. Just make sure your genesyscloud_routing_skill resource is created before the queue tries to reference it. You might need to add an explicit depends_on if the provider doesn’t catch the implicit dependency.

I’ve seen this pattern save hours of debugging when integrating tracing into infrastructure code. The nested block syntax is tempting for brevity, but it’s a trap in Terraform when you’re adding instrumentation layers. Stick to the flat resource references. It’s more verbose, yes, but it works.