Zero downtime rotation of Genesys Cloud OAuth secrets via Terraform

Looking for the cleanest way to rotate OAuth client secrets in Genesys Cloud without killing existing sessions. We’re managing everything via the CX-as-Code Terraform provider, and the default behavior seems to force a destroy/create cycle on the genesys_cloud_oauth_client resource whenever the secret changes. That’s a hard no for us. We can’t afford the downtime while the new client gets provisioned.

I’ve tried using the lifecycle block with ignore_changes = ["secret"] to prevent drift, but then the state file falls out of sync with reality, which defeats the purpose of IaC. The API docs mention creating a new secret alongside the old one, but the Terraform provider doesn’t seem to expose a direct endpoint for adding secondary secrets. It looks like it wants to replace the whole client object.

Has anyone hacked this? Maybe a script that calls the raw REST API to add the new secret before Terraform runs? I’m considering writing a local-exec provisioner to hit /api/v2/oauth/clients/{id} directly, but that feels messy. Any thoughts on keeping the state sane while rotating?

The destroy/create cycle happens because the secret hash changes, triggering a full resource replacement in Terraform. You can’t avoid that with the standard genesys_cloud_oauth_client resource without breaking the contract. Creating a second client and updating your downstream configs before deleting the old one is the only safe path.

You’re right about the destroy/create cycle being a hard block. The lifecycle ignore_changes trick just masks the problem by leaving the state out of sync, which causes drift later.

I’ve handled this by managing the rotation outside the standard resource update. You create the new client, update the consuming apps to point to the new client ID, then delete the old one. It’s manual but safe.

Here is the flow using the REST API directly since the Terraform provider doesn’t support “rotate” natively:

  1. POST /api/v2/oauth/clients with the same name/scopes but new secret.
  2. Update your app configs to use the new clientId.
  3. DELETE /api/v2/oauth/clients/{oldId} once traffic shifts.

Don’t try to automate the delete in the same apply block as the create. You’ll race the token refresh. Better to use a CI/CD step that waits for health checks before the final cleanup.