Define a Genesys Cloud Queue with Skills in Terraform Using the CX as Code Provider

Define a Genesys Cloud Queue with Skills in Terraform Using the CX as Code Provider

What You Will Build

  • You will create a Genesys Cloud queue entity that includes specific routing skills and associated routing rules using Infrastructure as Code.
  • This tutorial uses the mcknife/genesyscloud Terraform provider (commonly referred to as the CX as Code provider).
  • The implementation is written in HashiCorp Configuration Language (HCL) for Terraform.

Prerequisites

  • Terraform Version: 1.0 or later.
  • Provider Version: mcknife/genesyscloud version 1.18.0 or later.
  • Genesys Cloud Account: An account with Administrator permissions to create queues and manage skills.
  • Authentication: A Service Account with OAuth2 Client Credentials. The account must have the queue:queue and routing:skill scopes.
  • Environment Variables: GENESYS_CLOUD_OAUTH_CLIENT_ID and GENESYS_CLOUD_OAUTH_CLIENT_SECRET must be set in your execution environment.

Authentication Setup

The Genesys Cloud Terraform provider handles OAuth2 authentication automatically via environment variables. You do not need to write explicit authentication code in your HCL files. However, you must ensure the provider block is configured correctly to use these credentials.

Create a main.tf file and initialize the provider. This block establishes the connection to the Genesys Cloud API using the client credentials flow.

terraform {
  required_providers {
    genesyscloud = {
      source  = "mcknife/genesyscloud"
      version = "~> 1.18"
    }
  }
}

provider "genesyscloud" {
  # The provider automatically reads GENESYS_CLOUD_OAUTH_CLIENT_ID 
  # and GENESYS_CLOUD_OAUTH_CLIENT_SECRET from environment variables.
  # No additional configuration is required for standard OAuth2 flows.
}

If you are running this locally, ensure your shell exports these variables:

export GENESYS_CLOUD_OAUTH_CLIENT_ID="your_client_id_here"
export GENESYS_CLOUD_OAUTH_CLIENT_SECRET="your_client_secret_here"

Implementation

Step 1: Define the Routing Skills

Before creating a queue, you must define the skills that the queue will require. Genesys Cloud queues route conversations based on whether agents possess specific skills. In Terraform, skills are managed via the genesyscloud_routing_skill resource.

The skill definition requires a unique name and a description. It is critical that the skill name is unique within your organization, as Genesys Cloud does not allow duplicate skill names.

resource "genesyscloud_routing_skill" "technical_support" {
  name        = "Technical Support L1"
  description = "Level 1 technical support skill for hardware issues"
}

resource "genesyscloud_routing_skill" "billing_specialist" {
  name        = "Billing Specialist"
  description = "Skill required for handling billing inquiries and disputes"
}

Error Handling: If you attempt to apply this configuration twice without state management, Terraform will fail because the skill already exists. The provider handles import of existing resources if the ID is known, but for new resources, ensure the names are unique. If you receive a 409 Conflict error, it means a skill with that name already exists. You must either change the name or import the existing resource into your state.

Step 2: Define the Queue with Skills

Now that the skills exist, you can create the queue. The genesyscloud_routing_queue resource is the core entity. You must reference the IDs of the skills created in Step 1.

The queue configuration includes:

  1. Name and Description: Identifiable metadata.
  2. Skills: A list of skill IDs that agents must possess to receive work from this queue.
  3. Routing Rules: A list of rules that determine how conversations are matched to agents based on skill priority and other criteria.
  4. Wrap-up Policy: Defines how long agents have to wrap up a conversation.
resource "genesyscloud_routing_queue" "tech_support_queue" {
  name        = "Technical Support Queue"
  description = "Primary queue for L1 technical support inquiries"

  # Reference the skill IDs defined in Step 1
  skills = [
    genesyscloud_routing_skill.technical_support.id,
    genesyscloud_routing_skill.billing_specialist.id
  ]

  # Enable the queue immediately
  enabled = true

  # Wrap-up policy configuration
  wrapup_policy {
    type = "OPTIONAL"
    timeout_seconds = 300
  }

  # Routing rules define how the queue matches conversations to agents
  routing_rules {
    label = "Technical Support Rule"
    type  = "SKILL"
    
    # This rule requires the agent to have the Technical Support skill
    # The priority determines the order of evaluation if multiple rules exist
    priority = 1
    
    # Skill configuration within the rule
    skill {
      id         = genesyscloud_routing_skill.technical_support.id
      expression = "skill_level >= 1"
    }
  }

  # Optional: Set the default language for the queue
  # language_id = "en-US" 
}

Explanation of Parameters:

  • skills: This is a list of string IDs. These IDs correspond to the id attribute of the genesyscloud_routing_skill resources. The queue will only route to agents who have all specified skills unless routing rules specify otherwise.
  • routing_rules: This block defines the logic for matching. The type “SKILL” indicates that matching is based on skill proficiency. The expression field uses a simple syntax to check skill levels.
  • wrapup_policy.type: Options include OPTIONAL, REQUIRED, or NONE. OPTIONAL allows agents to proceed to the next task after the timeout if they do not manually wrap up.

Step 3: Verify and Apply the Configuration

After defining the resources, you must initialize the provider and plan the changes. This step ensures that Terraform can reach the Genesys Cloud API and that the configuration is valid.

Run the following commands in your terminal:

# Initialize the provider
terraform init

# Validate the configuration syntax
terraform validate

# Preview the changes
terraform plan

The terraform plan output will show the resources to be created. Look for the following in the output:

Terraform will perform the following actions:

  # genesyscloud_routing_skill.billing_specialist will be created
  + resource "genesyscloud_routing_skill" "billing_specialist" {
      + id          = (known after apply)
      + name        = "Billing Specialist"
      + description = "Skill required for handling billing inquiries and disputes"
    }

  # genesyscloud_routing_skill.technical_support will be created
  + resource "genesyscloud_routing_skill" "technical_support" {
      + id          = (known after apply)
      + name        = "Technical Support L1"
      + description = "Level 1 technical support skill for hardware issues"
    }

  # genesyscloud_routing_queue.tech_support_queue will be created
  + resource "genesyscloud_routing_queue" "tech_support_queue" {
      + id          = (known after apply)
      + name        = "Technical Support Queue"
      + description = "Primary queue for L1 technical support inquiries"
      + enabled     = true
      + skills      = [
          + (known after apply), # Resolved from technical_support.id
          + (known after apply), # Resolved from billing_specialist.id
        ]
      + wrapup_policy {
          + timeout_seconds = 300
          + type            = "OPTIONAL"
        }
      + routing_rules {
          + label    = "Technical Support Rule"
          + type     = "SKILL"
          + priority = 1
          + skill {
              + id         = (known after apply)
              + expression = "skill_level >= 1"
            }
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

If the plan looks correct, apply the changes:

terraform apply

You will be prompted to confirm. Type yes and press Enter. Terraform will call the Genesys Cloud API to create the skills first, then the queue. The order is determined by the dependency graph: the queue depends on the skills, so Terraform creates the skills first.

Complete Working Example

The following is a complete, copy-pasteable main.tf file. Save this file in an empty directory, set your environment variables, and run terraform init followed by terraform apply.

terraform {
  required_providers {
    genesyscloud = {
      source  = "mcknife/genesyscloud"
      version = "~> 1.18"
    }
  }
}

provider "genesyscloud" {
  # Authentication is handled via environment variables:
  # GENESYS_CLOUD_OAUTH_CLIENT_ID
  # GENESYS_CLOUD_OAUTH_CLIENT_SECRET
}

# --- Resource 1: Define Skills ---

resource "genesyscloud_routing_skill" "skill_tech_l1" {
  name        = "Tech Support L1"
  description = "Basic technical support capabilities"
}

resource "genesyscloud_routing_skill" "skill_billing" {
  name        = "Billing Expert"
  description = "Advanced billing and payment processing skill"
}

# --- Resource 2: Define the Queue ---

resource "genesyscloud_routing_queue" "main_support_queue" {
  name        = "Main Support Queue"
  description = "Central queue for all customer support inquiries"

  # Assign the skills defined above
  skills = [
    genesyscloud_routing_skill.skill_tech_l1.id,
    genesyscloud_routing_skill.skill_billing.id
  ]

  enabled = true

  # Wrap-up policy: Agents have 5 minutes to wrap up
  wrapup_policy {
    type            = "OPTIONAL"
    timeout_seconds = 300
  }

  # Routing Rule 1: Match agents with Tech Support L1 skill
  routing_rules {
    label    = "Route to Tech L1"
    type     = "SKILL"
    priority = 1

    skill {
      id         = genesyscloud_routing_skill.skill_tech_l1.id
      expression = "skill_level >= 1"
    }
  }

  # Routing Rule 2: Match agents with Billing Expert skill
  # This rule has higher priority (lower number) so it is evaluated first
  routing_rules {
    label    = "Route to Billing Expert"
    type     = "SKILL"
    priority = 2

    skill {
      id         = genesyscloud_routing_skill.skill_billing.id
      expression = "skill_level >= 1"
    }
  }
}

# --- Output: Print the Queue ID for reference ---

output "queue_id" {
  value       = genesyscloud_routing_queue.main_support_queue.id
  description = "The ID of the created Genesys Cloud queue"
}

output "skill_tech_l1_id" {
  value       = genesyscloud_routing_skill.skill_tech_l1.id
  description = "The ID of the Tech Support L1 skill"
}

Common Errors & Debugging

Error: 409 Conflict - Skill Already Exists

What causes it: You attempted to create a skill with a name that already exists in your Genesys Cloud organization. Genesys Cloud enforces unique skill names.

How to fix it:

  1. Check your Genesys Cloud admin console for existing skills.
  2. Change the name attribute in your genesyscloud_routing_skill resource to a unique value.
  3. Alternatively, if you want to manage an existing skill with Terraform, you must import it. Run terraform import genesyscloud_routing_skill.existing_skill <skill_id> and add the resource definition to your code without the create lifecycle.

Error: 400 Bad Request - Invalid Skill ID

What causes it: The skills list in the genesyscloud_routing_queue resource contains a skill ID that does not exist or is invalid.

How to fix it:

  1. Ensure that the genesyscloud_routing_skill resources are defined in the same Terraform configuration.
  2. Verify that you are referencing the .id attribute correctly (e.g., genesyscloud_routing_skill.skill_tech_l1.id).
  3. Check for typos in the resource reference names.

Error: 403 Forbidden - Insufficient Permissions

What causes it: The OAuth client credentials used do not have the necessary scopes to create queues or skills.

How to fix it:

  1. Go to the Genesys Cloud Admin Console.
  2. Navigate to Security > Security Profiles.
  3. Edit the security profile assigned to your service account.
  4. Ensure the following permissions are checked:
    • queue:queue (Create, Update, Delete)
    • routing:skill (Create, Update, Delete)
  5. Save the changes. The new permissions may take up to 5 minutes to propagate.

Error: 422 Unprocessable Entity - Invalid Routing Rule Expression

What causes it: The expression field in the routing_rules block contains invalid syntax.

How to fix it:

  1. Review the expression syntax. Common valid expressions include skill_level >= 1, skill_level > 0, or true.
  2. Ensure that the skill ID referenced in the rule exists and is correctly formatted.
  3. Check for special characters that may need escaping.

Official References