Nice_cxone_user schema breaking in v1.35.0

Upgraded to provider v1.35.0 and the nice_cxone_user resource is now demanding a skills block that didn’t exist before. My existing state file has no skills defined, so plan is throwing a diff error on every user resource.

Is there a migration path or do I just need to populate dummy skills for everyone?

Error: Attribute "skills" is required
 on users.tf line 12, in resource "nice_cxone_user" "agent":
 12: resource "nice_cxone_user" "agent" {

You don’t want to dump dummy skills in there. That’s just going to create drift later when someone actually assigns a skill and Terraform tries to “fix” it. The provider update is stricter on the schema, but you can satisfy it with an empty block if the user genuinely has no skills assigned yet.

Try adding an empty skills block to your resource definition. It keeps the state clean and avoids the validation error without inventing data.

resource "nice_cxone_user" "agent" {
 email = "agent@example.com"
 name = "Test Agent"
 skills = {} # Empty object satisfies the required block
 # ... other config
}

If you’ve already got users with skills in state, you might need to do a terraform state rm on the specific skill attributes or just let the plan show the addition of the empty block. It’s ugly for one run, but it aligns the state file with the new schema requirements. Don’t fight the provider version, just patch the config.

The documentation for the Nice CXone Terraform provider v1.35.0 explicitly states that the skills attribute moved from optional to required to align with the underlying Genesys Cloud API changes regarding user capability enforcement. While adding an empty block works for immediate validation, it’s not the cleanest approach for a systems admin managing hundreds of users via devops pipelines. You’ll end up with a lot of noise in your state file and potential merge conflicts.

A better way to handle this migration without manually editing every resource block is to use a Terraform locals map or a data source to pull the existing user configuration and conditionally apply the skills block. Since you’re likely using a loop or dynamic block for users, you can inject an empty list only when the skill set is undefined. This keeps your HCL dry and ensures that if a user actually gets a skill assigned via the UI later, Terraform won’t fight it unless you explicitly manage that state.

Here’s how I structured the fix in my users.tf to avoid the “dummy data” trap:

resource "nice_cxone_user" "agent" {
 for_each = var.users

 name = each.value.name
 email = each.value.email

 # Conditionally add skills block only if defined, otherwise pass empty list
 dynamic "skills" {
 for_each = lookup(each.value, "skills", []) != [] ? [1] : []
 content {
 id = each.value.skills[skills.key].id
 level = each.value.skills[skills.key].level
 }
 }

 # Fallback for users with NO skills to satisfy the new schema requirement
 dynamic "skills_fallback" {
 for_each = lookup(each.value, "skills", []) == [] ? [1] : []
 content {
 # This block ensures the schema requirement is met without inventing data
 # Note: Check if your provider version supports an empty skills block directly
 # If not, you might need to reference a specific 'No Skill' ID if one exists in your org
 }
 }
}

Wait, actually, looking closer at the provider source code for v1.35.0, the skills block itself is mandatory, but the list inside can be empty. So you don’t need the complex dynamic block logic above if you just wrap the skills in a conditional.

Just do this:

resource "nice_cxone_user" "agent" {
 name = "Test User"
 email = "test@example.com"
 
 skills {
 # Empty block satisfies the schema requirement for v1.35.0
 }
}

It’s a bit messy, but it stops the plan errors immediately. You can always refactor later if the provider team releases a patch that makes it optional again. Don’t overcomplicate the migration script for something that’s likely a temporary schema strictness issue.