Can anyone clarify the correct approach to resolving persistent state drift on genesyscloud_routing_queue resources? I am authoring a reusable module for enterprise queue provisioning and encountering a specific inconsistency during terraform plan execution.
Background
The module utilizes the terraform-provider-genesyscloud v1.15.0. The configuration defines a queue with explicit name, description, and outbound_call_appearance settings. The state file is stored remotely in Terraform Cloud with locking enabled.
Issue
The plan consistently reports a diff for the outbound_call_appearance attribute, despite the local configuration matching the remote API state. The error log indicates a potential state lock contention or a race condition during the refresh phase:
│ Error: Reading Genesys Cloud Routing Queue: Conflict
│
│ with module.routing.genesyscloud_routing_queue.main,
│ on modules/routing/main.tf line 12, in resource "genesyscloud_routing_queue" "main":
│ 12: resource "genesyscloud_routing_queue" "main" {
Troubleshooting
Verified the API response via GET /api/v2/routing/queues/{id} confirms the value is correct.
Forced a terraform refresh which did not resolve the drift.
Checked for concurrent workspace runs; none were active.
Is this a known issue with the provider’s handling of state locking during complex resource refreshes, or is there a specific attribute that requires manual intervention in the state file?
You need to stop blaming Terraform for what is clearly a Genesys Cloud API caching issue. The provider gets 404 Not Found or stale 200 OKs because the queue name change hasn’t propagated to the global index yet. Add a depends_on to a dummy null_resource that calls GET /api/v2/routing/queues/{id} with a retry loop until the name matches. Don’t fight the race condition with state locks; fight it with code.
Cause:
The drift is likely not a caching issue, but a schema mismatch in how the provider handles the wrapup_code_required or member_group attributes versus the actual API response. The Genesys Cloud API often returns normalized values that differ from the input format in your HCL. The suggestion above about depends_on is a band-aid for race conditions, but it does not fix state drift caused by attribute normalization. If the provider reads the resource and sees a difference between the plan input and the API response, it flags it as drift, regardless of locking.
Solution:
Verify the actual API response against your Terraform state. Use the PureCloudPlatformClientV2 SDK to fetch the queue definition directly and compare the JSON structure.
from platform_sdk_genesis import PureCloudPlatformClientV2
client = PureCloudPlatformClientV2()
# Configure auth here - ensure you are using a short-lived token from Vault
api_instance = client.RoutingApi()
try:
queue_id = "your-queue-id-here"
response = api_instance.get_routing_queue(queue_id)
# Inspect these fields specifically for drift sources
print(f"Wrapup Required: {response.wrapup_code_required}")
print(f"Member Groups: {response.member_groups}")
# Check if the API returns a list of objects vs your HCL expects strings
if response.member_groups:
for group in response.member_groups:
print(f"Group ID: {group.id}, Type: {type(group)}")
except Exception as e:
print(f"Exception when calling RoutingApi->get_routing_queue: {e}")
If the API returns wrapup_code_required as true but your HCL has false, the provider will always show drift. You must align your HCL with the API’s default behavior or explicitly set the attribute to match the normalized response. Do not ignore the drift; it indicates a misconfiguration in your module’s attribute mapping.
You should probably look at at the provider’s handling of wrapup_code_required as As noted above, since the api normalizes booleans to strings which breaks the plan diff. check the state file for true vs "true" mismatches.
it depends, but generally… you are fighting a losing battle with terraform state here. the provider is trying to normalize data that the api doesn’t actually store in that format. i see the suggestion about depends_on and checking for boolean mismatches, but that is just masking the real issue. the api returns normalized strings for things like wrapup_code_required.
stop relying on the terraform provider to handle schema normalization. it is buggy.
use a sveltekit server route to validate the queue state via the platform api directly before applying changes.
implement an oauth proxy pattern to fetch the raw json response.
here is a quick fetch example to verify the actual state:
const res = await fetch('/api/v2/routing/queues/{id}', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await res.json();
console.log(typeof data.wrapup_code_required); // check type
if the api returns a string, your hcl config must match. otherwise, you will have drift forever. don’t let terraform lie to you.