| name | databricks-unity-catalog-setup |
| description | Set up Unity Catalog on Databricks workspaces. Use when the user asks to configure Unity Catalog, create a metastore, set up catalogs, schemas, external locations, storage credentials, or configure data governance. Covers Azure, AWS, and GCP. |
Unity Catalog Setup
Configure Unity Catalog end-to-end: metastores, storage credentials, external locations, catalogs, schemas, and grants.
Resource naming convention
All resource names in this skill (and its cloud-specific files) use <prefix> as a placeholder. Substitute it with a unique value derived from the conversation — customer name, project name, or workspace name. Examples:
<prefix>-catalog-dev → acme-catalog-dev
st<prefix>catalogdev (Azure storage account, alphanumeric only) → stacmecatalogdev
gs://<prefix>-catalog-dev → gs://acme-catalog-dev
Never use <prefix> literally — < and > are not valid in bash, SQL, HCL, or cloud resource names; literal use will fail loudly. Never reuse a prefix across deployments in the same cloud account — S3 / GCS bucket names and Azure storage account names are globally unique, and Databricks workspace names are unique per account.
If the customer hasn't provided a prefix, derive one from their workspace name or company name. Confirm it back to them before deploying.
How to Interact with the Customer
Apply MODERATE pushback. Ask clarifying questions when the request is ambiguous, but execute immediately when requirements are clear.
Must-ask if not specified:
- No storage strategy mentioned --> ask: "Do you want a self-managed metastore with your own storage, or are you using the Databricks-managed (vending machine) metastore?" Then recommend self-managed.
- No environment strategy mentioned --> ask: "Single catalog or per-environment catalogs (dev/stg/prod)?"
Strong warnings (state once, then proceed if they insist):
- Wants vending machine metastore for production --> warn: "Vending machine default storage is serverless-only. Classic compute cannot read it. I strongly recommend deploying a self-managed metastore with your own bucket/container."
Hard stops (do not proceed):
- Per-env catalogs sharing a single storage account/bucket --> refuse: "Each catalog must have its own dedicated storage account/bucket. Shared storage breaks blast-radius isolation and enables cross-environment data leakage. Create one storage account per catalog."
- DBFS for production data --> refuse: "DBFS is deprecated for production. Use external locations with UC-managed storage credentials."
- Workspace-local groups as UC grant principals --> refuse: "Unity Catalog requires account-level SCIM groups. Workspace-local groups are invisible to UC. Create account-level groups first."
Clear request with storage strategy --> just do it. No unnecessary questions.
Opinionated Defaults
These are the recommended production design. Apply them unless the user explicitly requests otherwise.
Workflow: UC via Terraform
For new workspaces: UC is part of the full workspace template (*-workspace-full). The workspace and UC deploy together.
For existing workspaces: Use the UC-only templates:
azure-unity-catalog -- access connector + ADLS + metastore + catalog + schemas
aws-unity-catalog -- IAM UC role + S3 + metastore + catalog + schemas
gcp-unity-catalog -- GCS + metastore + auto-generated SA + catalog + schemas
Fetch reference patterns from the Databricks Terraform repos before writing any Terraform, in this order:
https://github.com/databricks-solutions/technical-services-solutions (path workspace-setup/terraform-examples/) — START HERE. Self-contained UC scenarios curated by Databricks Shared Technical Services. Notably azure/azure-vnet-injection-uc/ (full UC stack: metastore + access connector + storage + external location + catalog) and the AWS/GCP BYOVPC scenarios with UC metastore create-or-attach. Actively maintained.
https://github.com/databricks/terraform-databricks-sra — SRA-compliant UC patterns with enterprise hardening (CMK on UC managed storage, account-level group/SP management, log delivery).
https://github.com/databricks/terraform-databricks-examples — broader UC examples per cloud. Updates more slowly — verify provider versions before relying on it.
IMPORTANT: Once you know the cloud, read the cloud-specific file for this skill:
- Azure --> read
AZURE.md in this skill directory
- AWS --> read
AWS.md in this skill directory
- GCP --> read
GCP.md in this skill directory
Workflow: UC via SDK/API (No Terraform)
For existing workspaces where Terraform is not managing the infrastructure.
Step 1: Create metastore (account API)
One metastore per region. Check if one already exists first.
PUT /api/2.1/accounts/{account_id}/metastores
{"name": "...", "storage_root": "s3://... or abfss://... or gs://...", "region": "..."}
Step 2: Configure data access (cloud-specific)
Read the cloud-specific file (AZURE.md / AWS.md / GCP.md) for the exact setup: IAM roles, access connectors, or GCP service accounts.
Step 3: Assign metastore to workspace
PUT /api/2.1/accounts/{account_id}/workspaces/{workspace_id}/metastore
{"metastore_id": "..."}
Step 4: Create catalogs + schemas (workspace API)
Databricks auto-creates a main catalog on metastore assignment. Use a different name for your catalogs.
CREATE CATALOG dev MANAGED LOCATION 's3://<prefix>-catalog-dev/';
CREATE SCHEMA dev.bronze;
CREATE SCHEMA dev.silver;
CREATE SCHEMA dev.gold;
Step 5: Grant access (workspace API)
GRANT USE_CATALOG ON CATALOG dev TO `data-engineers`;
GRANT USE_SCHEMA, CREATE_TABLE, CREATE_FUNCTION ON SCHEMA dev.bronze TO `data-engineers`;
GRANT USE_SCHEMA, SELECT ON SCHEMA dev.gold TO `data-analysts`;
External Location Hygiene
- One storage account/bucket per environment.
<prefix>-catalog-dev, <prefix>-catalog-stg, <prefix>-catalog-prod.
- One storage credential per cloud identity. Reuse the same credential across catalogs where the same IAM role / access connector / SA has access to all buckets.
- External locations: one per bucket/container. Each maps to a single storage path.
- Use
CREATE CATALOG ... MANAGED LOCATION (SQL) -- NOT storage_root in the REST API. MANAGED LOCATION correctly ties the catalog to the external location path. storage_root bypasses the binding.
- Grant
account users USE_CATALOG + USE_SCHEMA + SELECT on each catalog for basic read access. Without this, catalogs do not appear in the UI even with isolation_mode = OPEN.
Post-UC Checklist
After deploying Unity Catalog, verify every item:
- Metastore attached to workspace(s)
- Storage credentials created and marked as default
- External locations created (one per bucket/container)
- Per-env catalogs created with
MANAGED LOCATION pointing to external locations
- Medallion schemas created (bronze/silver/gold) in each catalog
- UC permissions granted to account-level groups (not users, not workspace-local groups)
- Human admins explicitly granted on UC objects. When the deploying SP is the metastore/catalog/external-location owner, human admins (even workspace admins) cannot see those objects in the UI until you grant them. ALWAYS include a
databricks_grants block giving the human-admin SCIM group ALL_PRIVILEGES on each catalog and MANAGE on each external location, OR transfer ownership of those objects to that group. Otherwise the customer's admins log in to a workspace where they can't see their own data. See identity-governance/SKILL.md error-handling section for the exact resource block.
- Verify with test query on BOTH classic compute (1+ workers) AND serverless SQL
- Classic:
spark.sql("SELECT * FROM dev.bronze.test_table")
- Serverless: run same query in SQL warehouse
- If classic fails with "Databricks Default Storage cannot be accessed using Classic Compute" --> you are on vending machine storage, deploy self-managed metastore
Cross-Links
- For workspace creation --> see
platform-provisioning skill
- For groups, users, service principals, and RBAC --> see
identity-governance skill
- For private networking --> see
private-networking skill