Zscaler Client Connector (ZCC) 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.
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/zcc provider is targeting first publication. Expect ~> 0.1.x initially. Pin to the exact patch version in production until 1.0 ships.
Response Contract
Every ZCC HCL response must include:
- Assumptions & version floor —
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).
- Risk category addressed — one or more of: auth misconfiguration, singleton/existing-only confusion, drift, schema-quirk handling (
condition_type, GUID), secret exposure.
- Chosen approach & tradeoffs.
- Validation plan —
terraform fmt -check, terraform validate, terraform plan -out=tfplan. No activation step exists for ZCC — changes apply directly to the API.
- Rollback notes — for singleton resources (
zcc_failopen_policy, zcc_web_app_service), terraform destroy only removes from state; the underlying API object persists. State the rollback procedure explicitly.
Workflow
- Capture context (see fields below).
- Diagnose intent using the routing table.
- Load only the matching reference file(s).
- Identify lifecycle type for the targeted resource:
- Standard CRUD:
zcc_trusted_network, zcc_forwarding_profile — full create / update / delete.
- Singleton:
zcc_failopen_policy — pre-existing per-company, create = update settings, delete = state-only.
- Existing-only:
zcc_web_app_service — create = locate by app_name and apply changes; delete = state-only.
- Propose HCL grounded in
references/resource-catalog.md — never invent attribute names.
- Validate and emit the Response Contract.
Capture Context — Fields to Confirm
| 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. |
Diagnose Before You Generate
| 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 |
| Cross-product question |
Prompt mentions ZPA / ZIA / ZTC alongside ZCC, or wires a ZCC trusted network into a ZIA tunnel context |
best-practices-skill → Cross-Product Equivalents |
Provider Block — Pick One
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_CLOUD with its optional annotation. Users need to discover that ZSCALER_CLOUD exists as a supported (but optional) parameter; condensing it to # ZSCALER_CLIENT_ID, ZSCALER_CLIENT_SECRET, ZSCALER_VANITY_DOMAIN hides that fact.
OneAPI (Zidentity tenants)
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")
}
Legacy ZCC v2 (pre-Zidentity tenants)
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.
Resource Hierarchy — Small On Purpose
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.
What ZCC Does Not Have
These are common LLM hallucinations because ZIA / ZTC / ZPA do have them. ZCC does not:
- ❌ No
order field on any resource — there is no rule-ordering concept.
- ❌ No
state = "ENABLED" style state field — active is a boolean, not a string enum.
- ❌ No
zcc_activation_status or activation step — changes apply directly.
- ❌ No
zia_workload_groups-style cross-product references.
- ❌ No predefined-rule mechanic.
- ❌ No
microtenant_id.
If you see a generated HCL block claiming any of these, reject it.
Naming Conventions
- Use descriptive names:
resource "zcc_trusted_network" "corp_office", not ... "this".
- Reserve
"this" for genuine singletons (zcc_failopen_policy).
- Standard files:
main.tf, variables.tf, outputs.tf, versions.tf, providers.tf.
Critical Schema Quirks
- ❌
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.
Credential Hygiene
- ❌ Never put
client_secret, private_key, or legacy zcc_client_secret in checked-in .tfvars.
- ❌ Never echo credentials in CI job logs.
- ✅ Use env vars:
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).
- ✅ Never mix OneAPI and legacy env vars in the same job — the provider will pick one based on
use_legacy_client and the rest are ignored, which makes misconfigurations silent.
- ✅ Mark every HCL variable carrying a credential
sensitive = true.
State considerations:
- The OneAPI client secret is not persisted to state.
- For singleton / existing-only resources, state contains a reference to the pre-existing API object — losing state means losing the binding, not the object.
Reference Files
Progressive disclosure:
- Auth & Providers — OneAPI vs legacy ZCC v2, env vars (and the trap of mixing them), credential hygiene.
- Resource Catalog — minimum-viable HCL per resource, singleton & existing-only patterns, data source cheat sheet.
- Troubleshooting — drift causes, schema quirks (
condition_type, GUID), import semantics, never-state rm, debug logging.
- Recent Provider Changes — auto-mined from the upstream provider CHANGELOG.
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.
Authoring Rule — Grounding for Uncatalogued Resources
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:
- Fetch the official Registry page first before generating any HCL:
- Resource:
https://registry.terraform.io/providers/zscaler/zcc/latest/docs/resources/<name_without_zcc_prefix>
- Data source:
https://registry.terraform.io/providers/zscaler/zcc/latest/docs/data-sources/<name_without_zcc_prefix>
- Ground every attribute name in that fetched page.
- State the Registry URL you used in the Response Contract
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.)
What This Skill Will Not Do
- Generate HCL with attribute names not documented on the official Terraform Registry page for that resource.
- Generate
order, state = "ENABLED", zcc_activation_status, or microtenant_id — none of these exist in ZCC.
- Recommend
terraform destroy on zcc_failopen_policy or zcc_web_app_service without warning that the API object persists.
- Cover provider development (the ZCC provider is built on
terraform-plugin-framework, not SDK v2 — different schema/diagnostic mechanics, out of scope).
1---2name: zcc-skill3description: 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).4license: MIT5---67# Zscaler Client Connector (ZCC) Skill89Diagnose-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.1011**Canonical source of truth** for resource/data-source schemas: <https://registry.terraform.io/providers/zscaler/zcc/latest/docs>.1213> **Provider status (as of 2026-04):** the `zscaler/zcc` provider is targeting first publication. Expect `~> 0.1.x` initially. Pin to the exact patch version in production until 1.0 ships.1415## Response Contract1617Every ZCC HCL response must include:18191. **Assumptions & version floor** — `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).202. **Risk category addressed** — one or more of: auth misconfiguration, singleton/existing-only confusion, drift, schema-quirk handling (`condition_type`, GUID), secret exposure.213. **Chosen approach & tradeoffs.**224. **Validation plan** — `terraform fmt -check`, `terraform validate`, `terraform plan -out=tfplan`. **No activation step exists for ZCC** — changes apply directly to the API.235. **Rollback notes** — for singleton resources (`zcc_failopen_policy`, `zcc_web_app_service`), `terraform destroy` only removes from state; the underlying API object persists. State the rollback procedure explicitly.2425## Workflow26271. **Capture context** (see fields below).282. **Diagnose intent** using the routing table.293. **Load only the matching reference file(s).**304. **Identify lifecycle type** for the targeted resource:31 - **Standard CRUD**: `zcc_trusted_network`, `zcc_forwarding_profile` — full create / update / delete.32 - **Singleton**: `zcc_failopen_policy` — pre-existing per-company, create = update settings, delete = state-only.33 - **Existing-only**: `zcc_web_app_service` — create = locate by `app_name` and apply changes; delete = state-only.345. **Propose HCL** grounded in `references/resource-catalog.md` — never invent attribute names.356. **Validate** and **emit the Response Contract**.3637## Capture Context — Fields to Confirm3839| Field | Why it matters | Default if missing |40| ----------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------- |41| Provider version | Pre-1.0; schemas may change. Latest stable is `~> 0.1.x`. | Assume latest `0.1.x` and state it. |42| **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. |43| 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. |44| Resource lifecycle| Standard CRUD vs. singleton vs. existing-only. Affects how to write `terraform destroy` and import. | Always check the catalog. |45| Terraform runtime | Affects `optional()`, `moved`, `import`, `removed` availability. | Assume `terraform ~> 1.9`. |4647## Diagnose Before You Generate4849| Failure category | Symptoms | Primary references |50| --------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |51| **Auth misconfiguration** | `401 unauthorized`, wrong env vars (mixing OneAPI's `ZSCALER_*` with legacy's `ZCC_*`) | [Auth & Providers](references/auth-and-providers.md) |52| **Singleton confusion** | Trying to `terraform destroy` `zcc_failopen_policy` and being surprised the API object survives | [Resource Catalog: Singleton & Existing-Only](references/resource-catalog.md#singleton--existing-only-resources) |53| **Existing-only confusion** | `zcc_web_app_service` create fails because `app_name` doesn't exist in the tenant | [Resource Catalog: zcc_web_app_service](references/resource-catalog.md#zcc_web_app_service-existing-only) |54| **Schema quirks** | `condition_type` drift, GUID-related update failures, `condition_type = 0 vs 1` confusion | [Troubleshooting: Schema Quirks](references/troubleshooting.md#schema-quirks) |55| **Resource catalog mismatch** | Invented attribute names; assuming ZCC has rule-ordering or activation (it does not) | [Resource Catalog](references/resource-catalog.md) |56| **Drift on every plan** | Bool flips, fields churn after import | [Troubleshooting: Drift Causes](references/troubleshooting.md#drift-causes) |57| **Secret exposure** | Credentials in `.tfvars`, in state, in CI logs | [Auth & Providers: Credential Hygiene](references/auth-and-providers.md#credential-hygiene) |58| **Cross-product question** | Prompt mentions ZPA / ZIA / ZTC alongside ZCC, or wires a ZCC trusted network into a ZIA tunnel context | `best-practices-skill` → [Cross-Product Equivalents](../best-practices-skill/references/cross-product-equivalents.md) |5960## Provider Block — Pick One6162The provider supports **two** auth paths. Pick based on whether the tenant has been migrated to Zidentity. **Do not default** — confirm with the user.6364> **Authoring rule (do not summarise):** when emitting an OneAPI provider block, reproduce the env-var comment list **verbatim** — including `ZSCALER_CLOUD` with its `optional` annotation. Users need to discover that `ZSCALER_CLOUD` exists as a supported (but optional) parameter; condensing it to `# ZSCALER_CLIENT_ID, ZSCALER_CLIENT_SECRET, ZSCALER_VANITY_DOMAIN` hides that fact.6566### OneAPI (Zidentity tenants)6768```hcl69terraform {70 required_version = "~> 1.9"71 required_providers {72 zcc = {73 source = "zscaler/zcc"74 version = "~> 0.1.0" # pin tight: pre-1.075 }76 }77}7879provider "zcc" {80 # In CI, set these env vars instead of hardcoding. The first three are required,81 # the fourth is optional and only used to target a non-production Zidentity environment.82 # ZSCALER_CLIENT_ID (required)83 # ZSCALER_CLIENT_SECRET (required; or ZSCALER_PRIVATE_KEY)84 # ZSCALER_VANITY_DOMAIN (required)85 # ZSCALER_CLOUD (optional — only set for non-prod, e.g. "beta")86}87```8889### Legacy ZCC v2 (pre-Zidentity tenants)9091```hcl92provider "zcc" {93 use_legacy_client = true94 # Env vars:95 # ZCC_CLIENT_ID, ZCC_CLIENT_SECRET96 # ZCC_CLOUD ← legacy cloud name97 # ZSCALER_USE_LEGACY_CLIENT=true98}99```100101❌ Do not set `zscaler_cloud = "zscaler"` on OneAPI — `zscaler` is a **legacy** cloud name. On OneAPI, omit `zscaler_cloud` entirely for production tenants.102103For private-key auth and credential hygiene, see [Auth & Providers](references/auth-and-providers.md).104105## Resource Hierarchy — Small On Purpose106107ZCC 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**.108109| Resource | Lifecycle | Purpose |110| ------------------------- | ----------------------- | ------------------------------------------------------------------ |111| `zcc_trusted_network` | Standard CRUD | Define a trusted network for evaluation by Client Connector. |112| `zcc_forwarding_profile` | Standard CRUD | How Client Connector forwards traffic; references trusted networks. |113| `zcc_failopen_policy` | **Singleton** (per company) | Settings on the company's pre-existing fail-open policy. |114| `zcc_web_app_service` | **Existing-only** | Update an already-existing web app service (bypass app). |115116For 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.117118| Data source | What it returns | Why it's read-only |119| ---------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- |120| `zcc_devices` | Enrolled Client Connector devices | Devices enroll via the agent install, not via API. |121| `zcc_admin_user` | Admin user record(s) | Admin users are managed in the ZCC console / Zidentity. |122| `zcc_admin_roles` | Admin role catalog | Roles are platform-defined. |123| `zcc_company_info` | Tenant metadata | Tenant config, not Terraform-managed. |124| `zcc_application_profiles` | Application profiles defined for the tenant | Profiles created via the ZCC console. |125| `zcc_predefined_ip_apps` | Catalog of predefined IP-based bypass apps | Catalog, not user-defined. |126| `zcc_custom_ip_apps` | Custom IP bypass apps | Read-only listing — provisioned via the console. |127| `zcc_process_based_apps` | Process-based bypass apps | Read-only listing — provisioned via the console. |128129See [Resource Catalog: Data Sources](references/resource-catalog.md#data-source-cheat-sheet) for the full schema of each.130131## What ZCC Does **Not** Have132133These are common LLM hallucinations because ZIA / ZTC / ZPA do have them. ZCC does **not**:134135- ❌ No `order` field on any resource — there is no rule-ordering concept.136- ❌ No `state = "ENABLED"` style state field — `active` is a boolean, not a string enum.137- ❌ No `zcc_activation_status` or activation step — changes apply directly.138- ❌ No `zia_workload_groups`-style cross-product references.139- ❌ No predefined-rule mechanic.140- ❌ No `microtenant_id`.141142If you see a generated HCL block claiming any of these, reject it.143144## Naming Conventions145146- Use descriptive names: `resource "zcc_trusted_network" "corp_office"`, not `... "this"`.147- Reserve `"this"` for genuine singletons (`zcc_failopen_policy`).148- Standard files: `main.tf`, `variables.tf`, `outputs.tf`, `versions.tf`, `providers.tf`.149150## Critical Schema Quirks151152- ❌ `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.153- ❌ `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.154- ❌ `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.155- ❌ `zcc_failopen_policy` is a singleton per company. Multiple `resource "zcc_failopen_policy"` blocks in the same state will fight each other.156157Full mechanics in [Resource Catalog](references/resource-catalog.md) and [Troubleshooting](references/troubleshooting.md).158159## Credential Hygiene160161- ❌ Never put `client_secret`, `private_key`, or legacy `zcc_client_secret` in checked-in `.tfvars`.162- ❌ Never echo credentials in CI job logs.163- ✅ Use env vars: `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).164- ✅ Never mix OneAPI and legacy env vars in the same job — the provider will pick one based on `use_legacy_client` and the rest are ignored, which makes misconfigurations silent.165- ✅ Mark every HCL variable carrying a credential `sensitive = true`.166167State considerations:168169- The OneAPI client secret is **not** persisted to state.170- For singleton / existing-only resources, state contains a reference to the pre-existing API object — losing state means losing the binding, not the object.171172## Reference Files173174Progressive disclosure:175176- [Auth & Providers](references/auth-and-providers.md) — OneAPI vs legacy ZCC v2, env vars (and the trap of mixing them), credential hygiene.177- [Resource Catalog](references/resource-catalog.md) — minimum-viable HCL per resource, singleton & existing-only patterns, data source cheat sheet.178- [Troubleshooting](references/troubleshooting.md) — drift causes, schema quirks (`condition_type`, GUID), import semantics, never-`state rm`, debug logging.179- [Recent Provider Changes](references/recent-provider-changes.md) — auto-mined from the upstream provider CHANGELOG.180181**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.182183## Authoring Rule — Grounding for Uncatalogued Resources184185ZCC ships a small surface (4 resources, 12 data sources), all enumerated in [Resource Catalog](references/resource-catalog.md). When asked about anything that isn't in the catalog:1861871. **Fetch the official Registry page first** before generating any HCL:188 - Resource: `https://registry.terraform.io/providers/zscaler/zcc/latest/docs/resources/<name_without_zcc_prefix>`189 - Data source: `https://registry.terraform.io/providers/zscaler/zcc/latest/docs/data-sources/<name_without_zcc_prefix>`1902. Ground every attribute name in that fetched page.1913. State the Registry URL you used in the Response Contract `Assumptions` section.192193❌ 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`.)194195## What This Skill Will Not Do196197- Generate HCL with attribute names not documented on the official Terraform Registry page for that resource.198- Generate `order`, `state = "ENABLED"`, `zcc_activation_status`, or `microtenant_id` — none of these exist in ZCC.199- Recommend `terraform destroy` on `zcc_failopen_policy` or `zcc_web_app_service` without warning that the API object persists.200- Cover provider development (the ZCC provider is built on `terraform-plugin-framework`, not SDK v2 — different schema/diagnostic mechanics, out of scope).