Use when writing, reviewing, or debugging Terraform HCL that uses the Zscaler Client Connector (ZCC) provider — covers provider auth (OneAPI / legacy ZCC v2 client), the small resource catalog (`zcc_trusted_network`, `zcc_forwarding_profile`, `zcc_failopen_policy` (singleton), `zcc_web_app_service` (existing-only)), the singleton + existing-only lifecycle pattern (no API delete on policy/web app service), the read-only data sources for users / devices / apps, and known quirks (`condition_type` accepting both `0` and `1`, GUID round-trips, plugin-framework semantics).
How this skill is triggered — by the user, by Claude, or both
Slash command
/zscaler-terraform-skills:zcc-skillThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Diagnose-first guidance for **end users writing Terraform HCL that consumes the `zscaler/zcc` provider**. ZCC manages Zscaler Client Connector configuration — trusted networks, forwarding profiles, fail-open policy, and bypass apps. This skill does not cover provider Go code.
Diagnose-first guidance for end users writing Terraform HCL that consumes the zscaler/zcc provider. ZCC manages Zscaler Client Connector configuration — trusted networks, forwarding profiles, fail-open policy, and bypass apps. This skill does not cover provider Go code.
Canonical source of truth for resource/data-source schemas: https://registry.terraform.io/providers/zscaler/zcc/latest/docs.
Provider status (as of 2026-04): the
zscaler/zccprovider is targeting first publication. Expect~> 0.1.xinitially. Pin to the exact patch version in production until 1.0 ships.
Every ZCC HCL response must include:
zscaler/zcc provider version (~> 0.1.x), Terraform/OpenTofu version, auth mode (ASK if not stated — provider supports both OneAPI and legacy ZCC v2 as first-class options), cloud target (only set if non-default), and whether the resource being touched is a singleton / existing-only (which means delete is a no-op).condition_type, GUID), secret exposure.terraform fmt -check, terraform validate, terraform plan -out=tfplan. No activation step exists for ZCC — changes apply directly to the API.zcc_failopen_policy, zcc_web_app_service), terraform destroy only removes from state; the underlying API object persists. State the rollback procedure explicitly.zcc_trusted_network, zcc_forwarding_profile — full create / update / delete.zcc_failopen_policy — pre-existing per-company, create = update settings, delete = state-only.zcc_web_app_service — create = locate by app_name and apply changes; delete = state-only.references/resource-catalog.md — never invent attribute names.| Field | Why it matters | Default if missing |
|---|---|---|
| Provider version | Pre-1.0; schemas may change. Latest stable is ~> 0.1.x. | Assume latest 0.1.x and state it. |
| Auth mode | OneAPI and legacy ZCC v2 are both first-class. Tenant must be migrated to Zidentity for OneAPI; otherwise legacy is the only option. | Ask. Do not default. State both options if unclear. |
| Cloud target | OneAPI: zscaler_cloud is optional and only set for non-prod (e.g. beta). Legacy: zcc_cloud names the legacy cloud. | Omit zscaler_cloud for production OneAPI. Ask for legacy. |
| Resource lifecycle | Standard CRUD vs. singleton vs. existing-only. Affects how to write terraform destroy and import. | Always check the catalog. |
| Terraform runtime | Affects optional(), moved, import, removed availability. | Assume terraform ~> 1.9. |
| Failure category | Symptoms | Primary references |
|---|---|---|
| Auth misconfiguration | 401 unauthorized, wrong env vars (mixing OneAPI's ZSCALER_* with legacy's ZCC_*) | Auth & Providers |
| Singleton confusion | Trying to terraform destroy zcc_failopen_policy and being surprised the API object survives | Resource Catalog: Singleton & Existing-Only |
| Existing-only confusion | zcc_web_app_service create fails because app_name doesn't exist in the tenant | Resource Catalog: zcc_web_app_service |
| Schema quirks | condition_type drift, GUID-related update failures, condition_type = 0 vs 1 confusion | Troubleshooting: Schema Quirks |
| Resource catalog mismatch | Invented attribute names; assuming ZCC has rule-ordering or activation (it does not) | Resource Catalog |
| Drift on every plan | Bool flips, fields churn after import | Troubleshooting: Drift Causes |
| Secret exposure | Credentials in .tfvars, in state, in CI logs | Auth & Providers: Credential Hygiene |
The provider supports two auth paths. Pick based on whether the tenant has been migrated to Zidentity. Do not default — confirm with the user.
Authoring rule (do not summarise): when emitting an OneAPI provider block, reproduce the env-var comment list verbatim — including
ZSCALER_CLOUDwith itsoptionalannotation. Users need to discover thatZSCALER_CLOUDexists as a supported (but optional) parameter; condensing it to# ZSCALER_CLIENT_ID, ZSCALER_CLIENT_SECRET, ZSCALER_VANITY_DOMAINhides that fact.
terraform {
required_version = "~> 1.9"
required_providers {
zcc = {
source = "zscaler/zcc"
version = "~> 0.1.0" # pin tight: pre-1.0
}
}
}
provider "zcc" {
# In CI, set these env vars instead of hardcoding. The first three are required,
# the fourth is optional and only used to target a non-production Zidentity environment.
# ZSCALER_CLIENT_ID (required)
# ZSCALER_CLIENT_SECRET (required; or ZSCALER_PRIVATE_KEY)
# ZSCALER_VANITY_DOMAIN (required)
# ZSCALER_CLOUD (optional — only set for non-prod, e.g. "beta")
}
provider "zcc" {
use_legacy_client = true
# Env vars:
# ZCC_CLIENT_ID, ZCC_CLIENT_SECRET
# ZCC_CLOUD ← legacy cloud name
# ZSCALER_USE_LEGACY_CLIENT=true
}
❌ Do not set zscaler_cloud = "zscaler" on OneAPI — zscaler is a legacy cloud name. On OneAPI, omit zscaler_cloud entirely for production tenants.
For private-key auth and credential hygiene, see Auth & Providers.
ZCC has a deliberately compact resource surface (4 resources). Most ZCC objects live in other systems (devices come from the agent, users from your IdP, apps from zia_*). The ZCC provider exists to manage policy on top of those objects.
| Resource | Lifecycle | Purpose |
|---|---|---|
zcc_trusted_network | Standard CRUD | Define a trusted network for evaluation by Client Connector. |
zcc_forwarding_profile | Standard CRUD | How Client Connector forwards traffic; references trusted networks. |
zcc_failopen_policy | Singleton (per company) | Settings on the company's pre-existing fail-open policy. |
zcc_web_app_service | Existing-only | Update an already-existing web app service (bypass app). |
For everything else (users, devices, apps), ZCC exposes data sources only — there is no resource counterpart, so do not try to manage them with resource blocks.
| Data source | What it returns | Why it's read-only |
|---|---|---|
zcc_devices | Enrolled Client Connector devices | Devices enroll via the agent install, not via API. |
zcc_admin_user | Admin user record(s) | Admin users are managed in the ZCC console / Zidentity. |
zcc_admin_roles | Admin role catalog | Roles are platform-defined. |
zcc_company_info | Tenant metadata | Tenant config, not Terraform-managed. |
zcc_application_profiles | Application profiles defined for the tenant | Profiles created via the ZCC console. |
zcc_predefined_ip_apps | Catalog of predefined IP-based bypass apps | Catalog, not user-defined. |
zcc_custom_ip_apps | Custom IP bypass apps | Read-only listing — provisioned via the console. |
zcc_process_based_apps | Process-based bypass apps | Read-only listing — provisioned via the console. |
See Resource Catalog: Data Sources for the full schema of each.
These are common LLM hallucinations because ZIA / ZTC / ZPA do have them. ZCC does not:
order field on any resource — there is no rule-ordering concept.state = "ENABLED" style state field — active is a boolean, not a string enum.zcc_activation_status or activation step — changes apply directly.zia_workload_groups-style cross-product references.microtenant_id.If you see a generated HCL block claiming any of these, reject it.
resource "zcc_trusted_network" "corp_office", not ... "this"."this" for genuine singletons (zcc_failopen_policy).main.tf, variables.tf, outputs.tf, versions.tf, providers.tf.zcc_trusted_network.condition_type accepts both 0 and 1 depending on what the API GET returns. Set whatever the GET response shows; omit on update to leave the remote value unchanged.zcc_trusted_network.guid is a read-only field set by the API on create and sent automatically on PUT updates. Don't try to set it manually.zcc_web_app_service.app_name must match an existing tenant object — create does not create a new web app service, it locates and updates one.zcc_failopen_policy is a singleton per company. Multiple resource "zcc_failopen_policy" blocks in the same state will fight each other.Full mechanics in Resource Catalog and Troubleshooting.
client_secret, private_key, or legacy zcc_client_secret in checked-in .tfvars.ZSCALER_CLIENT_ID, ZSCALER_CLIENT_SECRET, ZSCALER_VANITY_DOMAIN, ZSCALER_CLOUD (OneAPI) or ZCC_CLIENT_ID, ZCC_CLIENT_SECRET, ZCC_CLOUD, ZSCALER_USE_LEGACY_CLIENT=true (legacy ZCC v2).use_legacy_client and the rest are ignored, which makes misconfigurations silent.sensitive = true.State considerations:
Progressive disclosure:
condition_type, GUID), import semantics, never-state rm, debug logging.Cross-cutting engineering discipline (state organization, CI/CD, secret handling, testing strategy, modules, naming, versioning) lives in the sibling best-practices-skill — load it whenever the question is about how to structure or operate a Zscaler-Terraform repo rather than how to call a specific zcc_* resource.
ZCC ships a small surface (4 resources, 12 data sources), all enumerated in Resource Catalog. When asked about anything that isn't in the catalog:
https://registry.terraform.io/providers/zscaler/zcc/latest/docs/resources/<name_without_zcc_prefix>https://registry.terraform.io/providers/zscaler/zcc/latest/docs/data-sources/<name_without_zcc_prefix>Assumptions section.❌ Never invent attribute names. ✅ If the Registry page does not exist for a zcc_<name>, the resource does not exist — say so explicitly. (Reminder: zcc_* does not support order, state, zcc_activation_status, or microtenant_id.)
order, state = "ENABLED", zcc_activation_status, or microtenant_id — none of these exist in ZCC.terraform destroy on zcc_failopen_policy or zcc_web_app_service without warning that the API object persists.terraform-plugin-framework, not SDK v2 — different schema/diagnostic mechanics, out of scope).Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub zscaler/zscaler-terraform-skills --plugin zscaler-terraform-skills