How to Import Existing Genesys Cloud Resources into Terraform State
What You Will Build
- One sentence: This tutorial demonstrates how to add existing Genesys Cloud infrastructure (Queues, Users, Wrapskills) to your Terraform state file without recreating them.
- One sentence: This uses the Genesys Cloud Terraform Provider (
genesyscloud) and theterraform importcommand. - One sentence: The primary tool is the Terraform CLI, with HCL configuration files.
Prerequisites
- Terraform Version: 1.5.0 or later.
- Genesys Cloud Provider: Version 1.50.0 or later.
- Genesys Cloud Admin Credentials: A user with sufficient permissions to read the resources you are importing and write to the organization.
- Existing Resources: At least one Queue, User, or Wrapskill must already exist in your Genesys Cloud environment via the UI or API.
- Environment Variables:
GENESYS_CLOUD_REGION,GENESYS_CLOUD_CLIENT_ID, andGENESYS_CLOUD_CLIENT_SECRETmust be set.
Authentication Setup
Terraform handles authentication via the provider configuration. You do not need to write custom OAuth code. The provider manages the client credentials flow automatically.
Create a main.tf file with the provider block. Ensure you specify the region correctly. If your organization is in US East, use us-east-1. If you are in a sovereign cloud, use the appropriate endpoint.
terraform {
required_providers {
genesyscloud = {
source = "mikesplain/genesyscloud"
version = "~> 1.50"
}
}
}
provider "genesyscloud" {
# The provider automatically picks up GENESYS_CLOUD_CLIENT_ID and
# GENESYS_CLOUD_CLIENT_SECRET from environment variables.
# Explicitly setting the region is critical for API routing.
region = var.genesyscloud_region
}
variable "genesyscloud_region" {
description = "Genesys Cloud Region"
type = string
default = "us-east-1"
}
Initialize the provider to download the necessary binaries.
terraform init
If the provider initializes successfully, Terraform has validated that your credentials are reachable. If you receive a 401 or 403 error here, check your Client ID/Secret permissions in the Genesys Cloud Admin Console under Security > API Security.
Implementation
Step 1: Identify the Resource ID in Genesys Cloud
Terraform imports require the unique ID of the resource as it exists in Genesys Cloud. This is not the name or the email address. It is the UUID string returned by the REST API.
To find the ID of a Queue:
- Go to Admin > Routing > Queues.
- Click on the Queue you wish to import.
- Look at the URL bar. The format is typically
.../routing/queues/{queueId}. - Copy the
{queueId}.
Example Queue ID: 12345678-1234-1234-1234-123456789abc
To find the ID of a User:
- Go to Admin > Users.
- Click on the User.
- The URL format is
.../users/{userId}.
Example User ID: 87654321-4321-4321-4321-cba987654321
Step 2: Define the Resource in HCL
Before importing, you must define the resource in your Terraform configuration. Terraform needs to know what type of resource it is managing.
Critical Rule: Do not populate the configuration with values from the existing resource yet. Leave the configuration minimal or empty of specific values. The import command will populate the state file. After the import, you will run terraform plan to see the differences between your HCL and the actual Genesys Cloud state, then you will update the HCL to match.
Example: Importing a Queue
Create a file named queues.tf.
resource "genesyscloud_routing_queue" "my_existing_queue" {
# Leave these empty initially.
# The import command will fetch the real values.
# name = ""
# description = ""
# ...
}
Example: Importing a User
Create a file named users.tf.
resource "genesyscloud_user" "my_existing_user" {
# Leave empty initially
}
Example: Importing a Wrapskill
Wrapskills are often imported in bulk.
resource "genesyscloud_routing_wrapupcode" "my_existing_wrapup" {
# Leave empty initially
}
Step 3: Execute the Import Command
The syntax for importing is:
terraform import <ADDRESS> <ID>
Where <ADDRESS> is the resource address in your Terraform code (e.g., genesyscloud_routing_queue.my_existing_queue) and <ID> is the UUID from Genesys Cloud.
Importing a Queue
terraform import genesyscloud_routing_queue.my_existing_queue 12345678-1234-1234-1234-123456789abc
You will see output similar to:
genesyscloud_routing_queue.my_existing_queue: Importing from ID "12345678-1234-1234-1234-123456789abc"...
genesyscloud_routing_queue.my_existing_queue: Import prepared!
Prepared genesyscloud_routing_queue for import
genesyscloud_routing_queue.my_existing_queue: Refreshing state... [id=12345678-1234-1234-1234-123456789abc]
Import successful!
The resources that were imported are shown above. These resources are now in
your state file and can be managed using Terraform.
Importing a User
terraform import genesyscloud_user.my_existing_user 87654321-4321-4321-4321-cba987654321
Importing a Wrapskill
terraform import genesyscloud_routing_wrapupcode.my_existing_wrapup 99999999-9999-9999-9999-999999999999
Step 4: Reconcile State with Configuration
After the import, the resource exists in your terraform.tfstate file, but your HCL file is still empty. If you run terraform plan now, Terraform will see that the resource exists in the state but not in the configuration, and it will propose destroying the resource.
Do not apply this plan.
You must now update your HCL to match the attributes currently in Genesys Cloud.
- Run
terraform plan. - Observe the “Terraform will perform the following actions” section. It will show the current values in the state.
- Copy these values into your HCL file.
For the Queue example, update queues.tf:
resource "genesyscloud_routing_queue" "my_existing_queue" {
name = "Support Queue"
description = "Primary support queue"
# Note: Some attributes like 'outbound_email_enabled' or 'outbound_email_address'
# may require specific formatting. Check the provider documentation for exact schema.
# Membership is often handled via separate resources or sub-blocks.
# If the queue has agents, you must import the membership separately
# or define it in the queue resource if the provider supports it.
}
- Run
terraform planagain. - The output should say: “No changes. Your infrastructure matches the configuration.”
This confirms that your HCL is now the source of truth for the existing Genesys Cloud resource.
Complete Working Example
Below is a complete workflow for importing a Queue and a User.
1. Directory Structure
genesys-import-example/
├── main.tf
├── providers.tf
├── queues.tf
├── users.tf
└── variables.tf
2. providers.tf
terraform {
required_providers {
genesyscloud = {
source = "mikesplain/genesyscloud"
version = "~> 1.50"
}
}
}
provider "genesyscloud" {
region = var.genesyscloud_region
}
3. variables.tf
variable "genesyscloud_region" {
description = "Genesys Cloud Region"
type = string
default = "us-east-1"
}
4. queues.tf (Pre-Import)
resource "genesyscloud_routing_queue" "sales_queue" {
# Placeholder. Will be populated after import.
}
5. users.tf (Pre-Import)
resource "genesyscloud_user" "agent_jane" {
# Placeholder. Will be populated after import.
}
6. Execution Script
Save this as import.sh and make it executable (chmod +x import.sh).
#!/bin/bash
# Set environment variables if not already set
export GENESYS_CLOUD_CLIENT_ID="your_client_id"
export GENESYS_CLOUD_CLIENT_SECRET="your_client_secret"
export TF_VAR_genesyscloud_region="us-east-1"
# Initialize Terraform
echo "Initializing Terraform..."
terraform init
# Define IDs (Replace with real IDs from your Genesys Cloud instance)
QUEUE_ID="12345678-1234-1234-1234-123456789abc"
USER_ID="87654321-4321-4321-4321-cba987654321"
# Import Queue
echo "Importing Queue..."
terraform import genesyscloud_routing_queue.sales_queue $QUEUE_ID
# Import User
echo "Importing User..."
terraform import genesyscloud_user.agent_jane $USER_ID
echo "Import complete. Run 'terraform plan' to see differences."
echo "Update your HCL files to match the planned changes, then run 'terraform plan' again to verify."
7. Post-Import HCL (After Reconciliation)
After running the script and inspecting the terraform plan output, your files should look like this:
queues.tf
resource "genesyscloud_routing_queue" "sales_queue" {
name = "Sales Queue"
description = "Handles all inbound sales calls"
# Example of a complex attribute that might need attention
out_of_office_enabled = false
# Note: The provider may import membership lists.
# If you have agents in this queue, they will appear in the plan output.
# You may need to add 'genesyscloud_routing_queue_member' resources
# to manage them separately for better idempotency.
}
users.tf
resource "genesyscloud_user" "agent_jane" {
first_name = "Jane"
last_name = "Doe"
email = "jane.doe@company.com"
division_id = "12345678-1234-1234-1234-123456789abc" # The default division ID
# Users often have roles and skills. These are imported as separate resources
# or sub-blocks depending on the provider version.
}
Common Errors & Debugging
Error: Error: resource not found
Cause: The ID provided does not exist in the specified region, or the authenticated user does not have permission to read that resource.
Fix:
- Verify the ID is correct by checking the Genesys Cloud UI URL.
- Verify the region in your
providerblock matches the region where the resource was created. - Check the permissions of the API Client User. It must have
routing:queue:vieworuser:viewdepending on the resource.
Error: Error: expected name to be one of [value1, value2], got: value3
Cause: This usually happens during the terraform plan phase after import, not during the import itself. It means the HCL configuration has an invalid value for an enum field.
Fix: Check the Terraform Provider documentation for the allowed values for that specific field. For example, status in a user resource must be ACTIVE, SUSPENDED, or ARCHIVED.
Error: Error: Import failed: 409 Conflict
Cause: You are trying to import a resource that is already in the Terraform state file under a different address.
Fix: Run terraform state list to see if the resource is already tracked. If it is, use terraform state mv to move it to the new address, or remove it from state with terraform state rm before importing.
Error: Error: missing required argument "division_id"
Cause: Some resources, like Users or Queues, require a division_id to be set in the HCL configuration after import. The import command fetches the ID, but the HCL must explicitly declare it.
Fix: Add the division_id to your HCL resource block. You can find the Division ID in the Genesys Cloud Admin Console under Admin > Divisions or by looking at the divisionId field in the API response for the resource.
Error: Error: 403 Forbidden during Import
Cause: The API Client lacks the necessary OAuth scopes.
Fix:
- Go to Admin > Security > API Security.
- Select your API Client.
- Ensure the following scopes are added (example for Queues):
routing:queue:viewrouting:queue:edit(sometimes required for import depending on provider implementation)
- Regenerate the Client Secret if you changed scopes recently, and update your environment variables.