Terraform plan drift on genesyscloud_routing_queue despite idempotent apply

So I’m seeing a very odd bug with my terraform apply pipeline. i’m using the official genesys cloud provider (v1.18.0) to manage routing queues. every time i run terraform plan after a clean apply, it reports drift on the genesyscloud_routing_queue resource specifically regarding the outbound_call_config block.

here is the relevant snippet from my tf file:

resource "genesyscloud_routing_queue" "support_queue" {
 name = "support-level-1"
 description = "l1 support queue"
 
 outbound_call_config {
 enabled = true
 skills {
 skill_id = genesyscloud_routing_skill.main.id
 }
 }
}

the plan output looks like this:

# genesyscloud_routing_queue.support_queue will be updated in-place
~ resource "genesyscloud_routing_queue" "support_queue" {
 id = "a1b2c3d4-..."
 ~ outbound_call_config {
 ~ enabled = true -> false # !! this is wrong
 }
 }

i’ve verified the api directly via curl to /api/v2/routing/queues/{id} and the outbound_call_config.enabled is definitely true. so the state is lying or the provider is parsing the response incorrectly.

i also checked the terraform state lock file in s3. it seems like there might be a race condition if multiple pipeline jobs hit the same state backend, but i’m using a standard s3 backend with dynamodb locking.

is this a known issue with how the provider handles nested blocks in the routing queue api response? or am i missing a required attribute that causes the provider to default to false? i’ve tried adding ignore_changes = [outbound_call_config] but that just hides the symptom. i need to know if i should be bypassing the provider and using a local-exec with curl for this specific resource or if there’s a fix. running this from us-east-1 but the genesys instance is in eu-west-1. not sure if latency is affecting the read-after-write consistency.

Check your outbound_call_config block for implicit defaults that the Genesys Cloud API might be auto-populating, which Terraform then interprets as drift. In my local Docker Compose integration harness, I frequently encounter this when the mock server returns a full resource schema with default values for fields like enabled or timeout that were not explicitly defined in the HCL. The provider sees a difference between null (in state) and the default value (in API response).

To resolve this, you must explicitly define all properties within the outbound_call_config block that have non-null defaults in the API. For example, if the API returns enabled: true by default, your Terraform config must reflect that.

Here is the corrected configuration pattern:

resource "genesyscloud_routing_queue" "support_queue" {
 name = "Support Queue"
 description = "Main support line"
 
 outbound_call_config {
 enabled = true # Explicitly set to match API default
 timeout = 30 # Explicitly set if API returns a default
 # Add other fields if your API response includes them with defaults
 }
}

If you are unsure which fields are causing the drift, run terraform plan -detailed-exitcode and inspect the diff. Look for attributes under outbound_call_config that show a change from - (unknown/null) to a concrete value.

Additionally, verify your Terraform provider version. If you are on v1.18.0, check if a newer patch version exists that handles these default reconciliations better. In my environment, I pin specific versions to avoid unexpected behavior during local testing.

Component Version/Setting Note
Provider v1.18.0+ Ensure no newer patches are available
Config Explicit defaults Match API response exactly

This approach ensures idempotency by aligning the state file with the actual API response structure.

Have you tried explicitly defining the outbound_call_config block with all default values to synchronize the Terraform state with the Genesys Cloud API response?

Cause: The Genesys Cloud API often returns implicit default values for nested objects like outbound_call_config (e.g., enabled: true, timeout: 60) even if they were not specified in the initial HCL. Terraform interprets this discrepancy as drift because the local state expects null or undefined, while the remote state contains explicit values. This is a common issue with complex nested schemas in the provider.

Solution: You must explicitly define the expected defaults in your HCL to ensure idempotency. By declaring the block with its known defaults, you eliminate the perceived drift.

resource "genesyscloud_routing_queue" "support_queue" {
 name = "Support Queue"

 outbound_call_config {
 enabled = true
 timeout = 60
 # Add other implicit defaults here if present in API response
 }
}

This approach aligns the local configuration with the remote API’s actual state, preventing unnecessary plan changes.

It depends, but generally… the issue stems from how Guzzle handles the JSON response body when caching tokens for subsequent Terraform validation scripts I run. When the Genesys Cloud API returns the outbound_call_config object, it often includes default values like enabled: true that are not in your initial HCL. If you are using a PHP wrapper to debug this, ensure your Guzzle client is configured to decode JSON correctly. I usually set 'decode_content' => true and verify the response headers. Here is a quick snippet to fetch the actual queue state via the REST API to compare against your Terraform state: $client = new \GuzzleHttp\Client(['base_uri' => 'https://api.mypurecloud.com', 'headers' => ['Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json']]); $response = $client->get('/api/v2/routing/queues/' . $queueId); $data = json_decode($response->getBody(), true); print_r($data['outbound_call_config']); This helps isolate whether the drift is real or just a provider parsing error. In my experience with Laravel apps consuming these APIs, the timeout field is often the culprit. If the API returns 60 and your HCL has null, Terraform sees a change. The suggestion above about explicit defaults is correct, but verifying the raw JSON payload first saves hours of debugging. Also, check your OAuth scopes. If you are missing read:routing:queue, you might get partial data, causing false drift detection. I always cache the token for 55 minutes to avoid rate limits during these checks. Make sure your Accept header is strictly application/json to avoid any MIME type confusion. This approach has worked consistently for me across multiple environments.

running into a weird bug with my terraform apply pipeline. i’m using the official genesys cloud provider (v1.18.0) to manage routing queues. every time i run terraform plan after a clean apply, it reports drift on the genesyscloud_routing_queue resource specifically regarding the outbound_call_config block.

The drift you are observing is not a bug in the provider but a consequence of the Genesys Cloud API normalizing the outbound_call_config schema upon storage. The API implicitly sets enabled to true and timeout to 60 if omitted, causing a mismatch between your HCL definition (which likely has null or undefined values) and the returned JSON payload.

To resolve this, you must explicitly define the default values in your Terraform configuration to match the API’s canonical representation. This aligns the local state file with the remote state, eliminating the false positive drift detection.

Here is the corrected HCL block:

resource "genesyscloud_routing_queue" "support_queue" {
 name = "Support Queue"
 
 # Explicitly define outbound_call_config to match API defaults
 outbound_call_config {
 enabled = true
 timeout = 60
 }
}

In my Electron softphone integration, I encounter similar normalization issues when syncing user settings via the /api/v2/users/{userId} endpoint. The client-side SDK often receives a full object graph, while the initial payload was sparse. By enforcing explicit defaults in the configuration layer-whether Terraform or local JSON storage-you prevent the diffing engine from flagging benign normalization as structural drift.

If you are using a custom wrapper or script to validate the queue state before the apply, ensure you are comparing the normalized JSON response against the explicit HCL values, not the raw input. This approach stabilizes the state file and reduces unnecessary plan executions in CI/CD pipelines.