Migrating Genesys Cloud User Terraform Configurations for Provider v1.35.0 Schema Changes

Migrating Genesys Cloud User Terraform Configurations for Provider v1.35.0 Schema Changes

What You Will Build

  • You will refactor existing Terraform configurations for genesyscloud_user resources to comply with the breaking schema changes introduced in the Genesys Cloud Terraform Provider v1.35.0.
  • You will use the HashiCorp Configuration Language (HCL) to define user entities with the new required attribute structure for routing profiles and skill groups.
  • You will validate the configuration against the Genesys Cloud API to ensure successful user creation and update cycles without drift errors.

Prerequisites

  • Terraform: Version 1.5.0 or later.
  • Genesys Cloud Terraform Provider: Version 1.35.0 or later.
  • Genesys Cloud Org: An organization with API access and appropriate permissions to manage users (users:edit, users:view).
  • Environment Variables: GENESYS_CLOUD_REGION and GENESYS_CLOUD_CLIENT_ID/GENESYS_CLOUD_CLIENT_SECRET or GENESYS_CLOUD_ACCESS_TOKEN.
  • Dependencies: No external Python or JavaScript dependencies are required for this HCL-based tutorial, but a working HTTP client (like Postman or curl) is recommended for verifying API responses.

Authentication Setup

Terraform handles OAuth authentication automatically when the provider is configured. You must set the necessary environment variables or use a credentials file. For this tutorial, we assume environment variable injection.

# Set your Genesys Cloud region
export GENESYS_CLOUD_REGION="mypurecloud.com"

# Option 1: Client Credentials (Recommended for CI/CD)
export GENESYS_CLOUD_CLIENT_ID="your-client-id"
export GENESYS_CLOUD_CLIENT_SECRET="your-client-secret"

# Option 2: Access Token (For local debugging)
export GENESYS_CLOUD_ACCESS_TOKEN="your-access-token"

Initialize the Terraform provider to download the v1.35.0 binary.

terraform init

Implementation

Step 1: Identify the Breaking Change

In Genesys Cloud Terraform Provider versions prior to v1.35.0, the genesyscloud_user resource allowed implicit handling of routing profiles and skill groups. In v1.35.0, the schema for routing_profile and skill_groups was hardened. Specifically, the routing_profile block now requires explicit definition of the routing_profile_id, and the skill_groups block has stricter validation for skill_group_id and skill_level.

The breaking change primarily affects how you reference routing profiles. Previously, you might have relied on a lookup that was now deprecated or removed from the simple block structure. You must now explicitly pass the ID of an existing routing profile.

Old Schema (Pre-v1.35.0 - Deprecated/Removed):

# This structure is no longer valid in v1.35.0
resource "genesyscloud_user" "test_user" {
  name = "Test User"
  email = "test.user@example.com"
  
  # Deprecated implicit routing profile assignment
  routing_profile {
    name = "Default Routing Profile" 
  }
}

New Schema (v1.35.0+):
You must now use a data source to look up the routing profile ID and pass it explicitly.

Step 2: Define Data Sources for Dependencies

Before creating the user, you must resolve the dependencies. The genesyscloud_user resource requires a valid routing_profile_id. You will use the genesyscloud_routing_profile data source to fetch this ID.

# Fetch the default routing profile ID
data "genesyscloud_routing_profile" "default" {
  name = "Default Routing Profile"
}

# Fetch a specific skill group if required
data "genesyscloud_skill_group" "support_skill" {
  name = "Support Team Skill Group"
}

Step 3: Construct the Updated User Resource

Update your genesyscloud_user resource to use the new schema. The routing_profile block is now a single attribute routing_profile_id in the main user block, or part of a structured block depending on the exact sub-version of 1.35.x. In v1.35.0, the standard pattern is to assign the routing_profile_id directly if the resource schema supports it, or via a routing_profile block that strictly requires the ID.

Based on the v1.35.0 release notes, the routing_profile block was simplified. The name attribute inside routing_profile was removed in favor of id.

resource "genesyscloud_user" "test_user" {
  name  = "Jane Doe"
  email = "jane.doe@example.com"

  # New Schema: Explicit ID assignment
  routing_profile_id = data.genesyscloud_routing_profile.default.id

  # Optional: Assign skill groups with explicit IDs
  skill_groups {
    skill_group_id = data.genesyscloud_skill_group.support_skill.id
    skill_level    = 5
  }

  # Language settings
  languages {
    language_code = "en-US"
    proficiency   = 100
  }

  # Division (Optional but recommended for multi-division orgs)
  # division_id = data.genesyscloud_division.default.id
}

Step 4: Validate and Apply

Run terraform plan to verify that the configuration is syntactically correct and that the dependencies are resolved.

terraform plan

If the plan shows no errors and indicates a create or update action, proceed with apply.

terraform apply

Complete Working Example

This complete module demonstrates a robust setup for creating a user in Genesys Cloud using Provider v1.35.0. It includes error handling via data source lookups and explicit ID management.

terraform {
  required_providers {
    genesyscloud = {
      source  = "myntra/genesyscloud"
      version = ">= 1.35.0"
    }
  }
}

provider "genesyscloud" {
  # Credentials are pulled from environment variables
}

# 1. Lookup the Routing Profile
# This ensures we are referencing an existing profile by ID, complying with v1.35.0 schema
data "genesyscloud_routing_profile" "agent_profile" {
  name = "Agent Routing Profile"
}

# 2. Lookup a Skill Group (Optional)
data "genesyscloud_skill_group" "general_support" {
  name = "General Support"
}

# 3. Create the User with New Schema
resource "genesyscloud_user" "new_agent" {
  name  = "Agent Smith"
  email = "agent.smith@company.com"

  # CRITICAL: v1.35.0 requires explicit ID. 
  # The 'name' attribute inside routing_profile block is removed.
  routing_profile_id = data.genesyscloud_routing_profile.agent_profile.id

  # Skill Groups: Must use skill_group_id
  skill_groups {
    skill_group_id = data.genesyscloud_skill_group.general_support.id
    skill_level    = 8
  }

  # Languages: Required for voice/email routing
  languages {
    language_code = "en-US"
    proficiency   = 100
  }

  # Set the user to be active
  status = "ACTIVE"
}

# Output the User ID for reference
output "user_id" {
  value       = genesyscloud_user.new_agent.id
  description = "The ID of the newly created Genesys Cloud User"
}

Common Errors & Debugging

Error: Error: Invalid attribute name or Unsupported argument

What causes it:
You are using a configuration block from a pre-v1.35.0 version. Specifically, you might be using routing_profile { name = "..." } instead of routing_profile_id = "...". The v1.35.0 schema removed the ability to resolve routing profiles by name within the user resource block directly.

How to fix it:
Replace the routing_profile block with the routing_profile_id argument. Use a data source to look up the ID by name.

Code showing the fix:

# INCORRECT (Pre-v1.35.0)
resource "genesyscloud_user" "bad" {
  routing_profile {
    name = "Default"
  }
}

# CORRECT (v1.35.0+)
data "genesyscloud_routing_profile" "def" {
  name = "Default"
}

resource "genesyscloud_user" "good" {
  routing_profile_id = data.genesyscloud_routing_profile.def.id
}

Error: Error: creating User: 400 Bad Request

What causes it:
The routing_profile_id provided is invalid, does not exist, or belongs to a different division than the user is being created in. The Genesys Cloud API (/api/v2/users) validates the routing profile ID at creation time.

How to fix it:
Ensure the routing profile exists and is active. Verify that the division ID matches if you are specifying a division.

Debugging Code (API Verification):
Use the Genesys Cloud API to verify the routing profile exists.

GET /api/v2/routing/profiles/{routingProfileId}
Host: api.mypurecloud.com
Authorization: Bearer {access_token}

If this returns 404, the ID is incorrect. If it returns 200, verify the divisionId in the response matches the division you are targeting for the user.

Error: Error: Cycle: genesyscloud_user.new_agent, data.genesyscloud_routing_profile.agent_profile

What causes it:
This is rare but can happen if you have a circular dependency in your Terraform state, usually if you are creating a routing profile and a user in the same file and referencing them incorrectly. However, data sources are evaluated at plan time, so this error usually indicates a misconfigured resource dependency.

How to fix it:
Ensure that the data source for the routing profile is not dependent on the user resource. Data sources are read-only and should not create cycles. If you are creating the routing profile dynamically, ensure the user resource depends on the routing profile resource, not the data source.

# If creating the profile dynamically:
resource "genesyscloud_routing_profile" "new_profile" {
  name = "New Profile"
  # ...
}

resource "genesyscloud_user" "new_agent" {
  # Reference the resource, not a data source
  routing_profile_id = genesyscloud_routing_profile.new_profile.id
}

Official References