Migrating Genesys Cloud User Resources for Terraform Provider v1.35.0
What You Will Build
- You will update your Terraform configuration to handle the breaking schema changes in the
genesyscloud_userresource introduced in provider version 1.35.0. - You will use the HashiCorp Terraform CLI and the Genesys Cloud Terraform Provider to manage user identities.
- You will write HCL (HashiCorp Configuration Language) that aligns with the new required attributes for
division_idandrouting_email_address.
Prerequisites
- Terraform: Version 1.5.0 or higher.
- Genesys Cloud Terraform Provider: Version 1.35.0 or higher.
- OAuth Scopes:
user:read,user:write,routing:user:view,routing:user:write. - Environment: A Genesys Cloud organization where you have Admin or User Management permissions.
- Dependencies: None beyond the provider itself. Ensure your
versions.tfis updated.
Authentication Setup
The Genesys Cloud Terraform provider handles OAuth 2.0 Client Credentials flow automatically. You must provide the client_id and client_secret in your Terraform variables. Do not hardcode these values.
Create a terraform.tfvars file:
genesyscloud_client_id = "your-client-id-here"
genesyscloud_client_secret = "your-client-secret-here"
genesyscloud_base_url = "https://api.mypurecloud.com"
Configure the provider in main.tf:
terraform {
required_providers {
genesyscloud = {
source = "mikesir87/genesyscloud"
version = ">= 1.35.0"
}
}
}
provider "genesyscloud" {
client_id = var.genesyscloud_client_id
client_secret = var.genesyscloud_client_secret
base_url = var.genesyscloud_base_url
}
Verify the connection by running terraform plan with a minimal resource. If authentication fails, you will receive a 401 Unauthorized error from the provider.
Implementation
Step 1: Understanding the Breaking Change
In versions prior to 1.35.0, the genesyscloud_user resource allowed the division_id to be omitted, defaulting to the “Default” division. Additionally, routing_email_address was optional.
In version 1.35.0, the schema was tightened to align with the underlying Genesys Cloud API constraints. The division_id is now required unless the user is being created in the default division, in which case you must explicitly handle the default division ID. More critically, the provider now enforces stricter validation on routing_email_address to ensure it matches the user’s primary email or a verified alias.
If you attempt to run an existing configuration with version 1.35.0, terraform plan will fail with:
Error: Missing required argument
on users.tf line 1, in resource "genesyscloud_user" "example":
1: resource "genesyscloud_user" "example" {
The argument "division_id" is required, but no definition was found.
Step 2: Identifying the Default Division ID
To migrate existing users or create new ones in the default division, you must first retrieve the division_id of the default division. The API endpoint for this is /api/v2/organizations.
You can use the genesyscloud_organization data source to fetch this value dynamically.
data "genesyscloud_organization" "default" {
filter_name = "Default"
}
This data source queries the Genesys Cloud API. The response body from /api/v2/organizations includes the id field, which the data source exposes as data.genesyscloud_organization.default.id.
Step 3: Updating the User Resource Schema
You must now explicitly define division_id and ensure routing_email_address is correctly set.
Scenario A: New User in Default Division
resource "genesyscloud_user" "new_agent" {
name = "Jane Doe"
email = "jane.doe@example.com"
division_id = data.genesyscloud_organization.default.id
routing_email_address = "jane.doe@example.com"
user_types {
id = "agent"
}
}
Key changes:
division_idis explicitly set to the default division ID.routing_email_addressis set to match theemail.
Scenario B: New User in a Specific Division
If you are creating a user in a non-default division, you must use the genesyscloud_division data source or a hardcoded ID.
data "genesyscloud_division" "support" {
filter_name = "Support Division"
}
resource "genesyscloud_user" "support_agent" {
name = "John Smith"
email = "john.smith@example.com"
division_id = data.genesyscloud_division.support.id
routing_email_address = "john.smith@example.com"
user_types {
id = "agent"
}
}
Scenario C: Migrating Existing State
If you have existing users in your Terraform state, you must update the state file to include the division_id and routing_email_address attributes. The provider will detect the difference between the state and the API during the next terraform plan.
To update the state without changing the actual Genesys Cloud configuration, use terraform state rm and terraform import, or manually edit the state file if you are experienced with Terraform state management. However, the safer approach is to let Terraform detect the drift.
Run terraform plan. You will see updates like:
# genesyscloud_user.existing_agent will be updated in-place
~ resource "genesyscloud_user" "existing_agent" {
~ division_id = "default" -> "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
~ routing_email_address = null -> "agent@example.com"
id = "12345678-90ab-cdef-1234-567890abcdef"
name = "Existing Agent"
email = "agent@example.com"
# ... other attributes unchanged
}
Apply these changes with terraform apply. The provider will send a PUT request to /api/v2/users/{id} with the updated fields.
Step 4: Handling Email Verification
The Genesys Cloud API requires that the routing_email_address is verified. If you set routing_email_address to an email that is not the primary email and has not been verified, the API will return a 400 Bad Request.
To avoid this, always set routing_email_address to the same value as email unless you have a specific reason to use an alias and have already verified that alias via the API.
resource "genesyscloud_user" "complex_agent" {
name = "Complex Agent"
email = "complex.agent@example.com"
division_id = data.genesyscloud_organization.default.id
routing_email_address = "complex.agent@example.com" # Must be verified
user_types {
id = "agent"
}
}
If you need to use an alias, you must first add the alias to the user and verify it. This is typically done via the Genesys Cloud UI or a separate API call before the Terraform apply.
Complete Working Example
This example demonstrates a complete, production-ready configuration for managing users with the v1.35.0 provider.
# versions.tf
terraform {
required_providers {
genesyscloud = {
source = "mikesir87/genesyscloud"
version = ">= 1.35.0"
}
}
}
# provider.tf
provider "genesyscloud" {
client_id = var.genesyscloud_client_id
client_secret = var.genesyscloud_client_secret
base_url = var.genesyscloud_base_url
}
# variables.tf
variable "genesyscloud_client_id" {
description = "Genesys Cloud OAuth Client ID"
type = string
sensitive = true
}
variable "genesyscloud_client_secret" {
description = "Genesys Cloud OAuth Client Secret"
type = string
sensitive = true
}
variable "genesyscloud_base_url" {
description = "Genesys Cloud API Base URL"
type = string
default = "https://api.mypurecloud.com"
}
# data.tf
data "genesyscloud_organization" "default" {
filter_name = "Default"
}
data "genesyscloud_division" "sales" {
filter_name = "Sales Division"
}
# main.tf
resource "genesyscloud_user" "sales_agent" {
name = "Alice Sales"
email = "alice.sales@example.com"
division_id = data.genesyscloud_division.sales.id
routing_email_address = "alice.sales@example.com"
user_types {
id = "agent"
}
# Optional: Set language
languages {
code = "en-US"
order = 1
}
}
resource "genesyscloud_user" "default_agent" {
name = "Bob Default"
email = "bob.default@example.com"
division_id = data.genesyscloud_organization.default.id
routing_email_address = "bob.default@example.com"
user_types {
id = "agent"
}
}
Run the following commands to apply this configuration:
terraform init
terraform plan
terraform apply
Common Errors & Debugging
Error: Missing required argument division_id
Cause: You are using provider version 1.35.0+ but have not specified division_id in the genesyscloud_user resource.
Fix: Add division_id to your resource block. Use the genesyscloud_organization data source for the default division.
resource "genesyscloud_user" "example" {
name = "Example User"
email = "example@example.com"
division_id = data.genesyscloud_organization.default.id
routing_email_address = "example@example.com"
# ...
}
Error: Invalid routing_email_address
Cause: The routing_email_address does not match the email and has not been verified, or it is not a valid email format.
Fix: Ensure routing_email_address matches email or is a verified alias.
resource "genesyscloud_user" "example" {
name = "Example User"
email = "example@example.com"
routing_email_address = "example@example.com" # Must match or be verified
# ...
}
Error: 409 Conflict on User Creation
Cause: A user with the same email address already exists in Genesys Cloud.
Fix: Use terraform import to import the existing user into your Terraform state.
terraform import genesyscloud_user.example <user-id>
Error: 403 Forbidden
Cause: The OAuth client does not have the required scopes.
Fix: Ensure the client has user:write and routing:user:write scopes.