Your lakehouse lives in Azure Storage, not inside Databricks. The account type, performance tier, redundancy and network settings you choose decide cost, speed, DR options and security. Changing them later means moving data.
The options
| Option | Use with Databricks? | Notes |
|---|---|---|
| ADLS Gen2 (StorageV2 + hierarchical namespace enabled) | ✅ Recommended | Real directories, atomic renames, POSIX-style ACLs, best performance for Delta |
| Blob Storage without hierarchical namespace | ⚠️ Works | Slower for directory operations; legacy wasbs:// paths. Use for existing data, not new lakes. |
| Premium block blob (with HNS) | ✅ For latency-sensitive workloads | Higher cost per GB, lower latency; good for streaming checkpoints and small-file heavy loads |
| Azure Files / NetApp Files | ❌ Not for tables | Mount-style shares; not supported as Delta table storage |
| Azure SQL / Cosmos DB / Synapse | Sources and sinks | Through connectors or Lakehouse Federation, not as lake storage |
| OneLake (Fabric) | Interop | Read and write through ABFS paths, or mirror Unity Catalog into Fabric |
Warning
Hierarchical namespace must be chosen when the account is created. There's an in-place upgrade path, but it has conditions. Plan for HNS from the start.
Performance tier and access tier
- Standard (hot) for active lake data. This is the default choice.
- Premium block blob where many small reads and writes dominate.
- Cool/Cold/Archive only for data that is not part of a live Delta table, such as raw file archives. Tiering files under a Delta table breaks reads (archive) or makes them slow and expensive (cool/cold).
Redundancy and DR
| Redundancy | Protects against | Databricks consideration |
|---|---|---|
| LRS | Disk/rack failure | Cheapest; dev/test |
| ZRS | Zone failure | Good default for prod in regions with zones |
| GRS / RA-GRS | Region failure (async copy) | Failover is account-level; Delta tables may be inconsistent at the secondary. Test before relying on it. |
| GZRS / RA-GZRS | Zone + region | Same caveat |
For a tested DR, most teams use DEEP CLONE or job-driven replication to a second-region account, rather than raw GRS failover. See the Databricks DR post.
Layout
- One storage account per environment at minimum (dev, test, prod). Separate accounts per data domain if you need different owners, networks or keys.
- Containers per purpose:
landing,bronze,silver,gold, and one per Unity Catalog managed location. - Don't use the workspace's own managed resource group storage (DBFS root) for business data.
- Stay well below the per-account request and throughput limits. Very busy platforms spread load over several accounts.
Connecting securely: Unity Catalog
The recommended pattern needs no keys anywhere:
- Create an Access Connector for Azure Databricks (a resource with a managed identity).
- Grant the connector's identity Storage Blob Data Contributor on the storage account or container.
- In Databricks, create a storage credential that uses the access connector.
- Create external locations for the paths, then grant users rights on them.
CREATE STORAGE CREDENTIAL lake_mi
WITH (AZURE_MANAGED_IDENTITY = (ACCESS_CONNECTOR_ID =
'/subscriptions/0000-0000/resourceGroups/rg-data-prod/providers/Microsoft.Databricks/accessConnectors/ac-lake-prod'));
CREATE EXTERNAL LOCATION bronze_prod
URL 'abfss://bronze@stlakeprod.dfs.core.windows.net/'
WITH (STORAGE CREDENTIAL lake_mi);
GRANT READ FILES, WRITE FILES, CREATE EXTERNAL TABLE ON EXTERNAL LOCATION bronze_prod TO `data-engineers`;
The CREATE STORAGE CREDENTIAL SQL form isn't supported in every runtime. If it isn't in yours, create the credential in Catalog Explorer → External data → Credentials, or with Terraform, which is the usual choice for production.
Legacy access methods (avoid for new work)
| Method | Problem |
|---|---|
| Account keys in Spark config or notebooks | Full account access; key leakage; no per-user audit |
| SAS tokens | Expiry and rotation pain; broad scope |
| Service principal OAuth in cluster config | Secrets on clusters; bypasses Unity Catalog |
DBFS mounts (/mnt/...) | Everyone on the workspace shares the mount's identity; deprecated |
Network security
- Set the storage firewall to deny public access.
- Create private endpoints for both the
dfsandblobsub-resources in a VNet that your Databricks compute can reach. Linkprivatelink.dfs.core.windows.netandprivatelink.blob.core.windows.netprivate DNS zones. - Classic compute in an injected VNet can alternatively use service endpoints on the Databricks subnets.
- Serverless compute: configure a network connectivity configuration (NCC) in the account console. Add private endpoint rules to the storage account, then approve them on the storage side.
- Allow the access connector as a resource instance exception if you use the storage firewall without private endpoints.
Data protection settings
| Setting | Recommendation |
|---|---|
| Soft delete for blobs and containers | ✅ On (7–30 days). Recovers from accidental deletes. |
| Versioning | Optional; can add significant cost on busy Delta tables |
| Lifecycle management | ⚠️ Never delete or tier files under live Delta tables. Use VACUUM to remove old files. Apply lifecycle rules only to raw archives. |
| Immutability (WORM) | Only for archive containers; it blocks VACUUM and OPTIMIZE |
| Encryption | Microsoft-managed keys by default; customer-managed keys in Key Vault if required |
| Diagnostic logs | Send to Log Analytics for access auditing and throttling (503/ServerBusy) analysis |
Checklist
- StorageV2 with hierarchical namespace; ZRS (or better) for prod.
- Separate accounts per environment; containers per layer and managed location.
- Access connector + storage credential + external locations; no keys, SAS or mounts.
- Public access disabled; private endpoints (dfs + blob) with DNS; NCC for serverless.
- Soft delete on; no lifecycle rules on Delta table paths.
- Monitoring for throttling and capacity.