Every earlier lesson taught one control. This capstone assembles them. A reference architecture is just a choice of one control on each of the three connectivity paths (the scaffold from Stage 2.2), plus identity, governance, and encryption on top. You never invent a new map — you pick the closest of four floor plans and adapt.
A reference architecture is a floor plan for a secure building, and every question is "which lock goes on which of three doors — and what's the cheapest lock the regulator will accept?" ① user→workspace (front door) · ② compute↔control (staff intercom, outbound-only) · ③ compute→storage (loading dock). Pick the closest of four floor plans, harden the three doors with the cheapest lock that meets the compliance language, and be able to walk the packet and name what breaks at each hop.
| Path | Who talks to whom | Floor control (free) | Mandated upgrade |
|---|---|---|---|
| ① User → workspace | Browser / BI / REST → workspace URL | IP access list | Front-end Private Link + public access Disabled |
| ② Compute ↔ control | Cluster dials home (SCC relay, 443) | VNet injection + SCC | Back-end Private Link |
| ③ Compute → storage | Cluster reads/writes ADLS Gen2 | Storage firewall + Service Endpoint | Private Endpoint / NCC PE (+ firewall DEP) |
"We don't custom-build per customer — we pick the closest of four references and adapt. A lot is already off the public internet by default; Private Link, NCC private endpoints, and the firewall DEP just remove the last public-IP hop and stop a compromised notebook from reaching an attacker."
Four blueprints an Azure Databricks SA draws from memory. Switch the diagram between them — the same three doors, hardened differently — and click any box for the "what + why." IP sizing shows the node-count math.
The browser_authentication endpoint is one per region per DNS zone and a
single point of failure for SSO. Isolate it in a dedicated, delete-locked "web-auth workspace" so deleting
a spoke never breaks login for the others. And size subnets for peak — CIDR is immutable.
| Hop | Control(s) | WHY IT BREAKS without it |
|---|---|---|
| 1 · User → workspace URL | Front-end PL; IP ACL / public access Disabled | URL resolves to a public IP — open to the internet |
| 2 · SSO callback | browser_authentication PE | SSO callback has no route — login fails region-wide |
| 3 · CP schedules cluster | SCC/NPIP; VNet injection; delegation | VMs get public IPs + open inbound ports |
| 4 · Cluster → control plane | Back-end PL; SCC reversed call | Outbound rides the public internet to the relay |
| 5 · Cluster → ADLS Gen2 | Storage firewall; SE/PE; UC ext. location | Data path on public internet; storage open |
| 6 · Any other egress | UDR + Azure Firewall (DEP) | Compromised notebook exfiltrates to any host |
Terraform — VNet injection + SCC, sized for peak. Full module is the optional Stage 9 hands-on artifact.
resource "azurerm_virtual_network" "ws" {
address_space = ["10.50.0.0/16"] # /16: room for big subnets + PE subnets
}
resource "azurerm_subnet" "container" { # "private" subnet — private under SCC
address_prefixes = ["10.50.4.0/22"] # /22 -> ~1,019 nodes peak; immutable later
delegation { name = "dbx"; service_delegation { name = "Microsoft.Databricks/workspaces" } }
}
resource "azurerm_databricks_workspace" "this" {
sku = "premium" # Private Link / CMK / CSP require Premium
public_network_access_enabled = false # full-private (DEP); true for hybrid Standard
network_security_group_rules_required = "NoAzureDatabricksRules" # required with back-end PL
custom_parameters { no_public_ip = true } # SCC / No Public IP
}
Portal: Create → Azure Databricks → Networking → No Public IP = Yes, Deploy in your own VNet = Yes, Public Network Access Disabled (DEP), Required NSG Rules = NoAzureDatabricksRules.
Control plane / SCC relay: *.azuredatabricks.net · data-plane: adb-dp-<id>.<n>.azuredatabricks.net
· CDN assets: *.cloud.databricksusercontent.com — all 443. Don't route the SCC relay /
back-end-PL traffic through the firewall (already private; needless hop).
The pre-flight checklist laid over the three doors. For each door, ask: what's the floor, and what do I add only when a mandate pays for it? Toggle the diagram between the floor (free, always-on) and the mandated upgrades; click any box for the "what + why."
When someone asks "is this workspace secure?", don't recite features — walk the three doors and at each name (a) the floor control and (b) the mandated upgrade. Ten MUST items are the airframe; five amber items (back-end PL, front-end PL, storage PEs, CMK, firewall DEP) are bolt-ons only when the regulatory profile pays for the cost.
| Item | Tier | Always do? | Trade-off / when overkill |
|---|---|---|---|
| VNet injection + SCC | Any | Yes | None — the floor |
| Size subnets for peak | Any | Yes | Free; only failure is too small |
| NAT gateway egress | Any | Yes | Small hourly + per-GB |
| Storage firewall + Service Endpoints | Any | Yes | Free; default storage choice |
| Premium plan | Premium | Yes | Higher per-DBU cost |
| SSO + SCIM + MFA + separate admins | Any | Yes | Setup effort only |
| Unity Catalog for governed data | Any | Yes | Migration effort |
| Cluster policies + UC access mode | Premium | Yes | Friction for power users |
| Audit logging / system tables | Any (Preview) | Yes | Storage/SIEM cost |
| IaC for everything | Any | Yes | Up-front authoring |
| Back-end Private Link | Premium | When internal traffic must be private | Per-endpoint cost |
| Front-end PL + public access Disabled | Premium | When "no public ingress" mandated | Transit VNet, DNS, web-auth |
| Private Endpoints to storage | Any | When private IP on storage mandated | Per-GB — validate first |
| CMK | Premium | When key custody mandated | Key Vault ops + lockout risk |
| Azure Firewall DEP | Any | When exfil-sensitive | Cost + hop; don't route SCC through it |
# Item 4.3 — IP access list (enforcement must be ON, else stored-but-not-applied)
resource "databricks_workspace_conf" "this" {
custom_config = { "enableIpAccessLists" = "true" } # turn the feature ON
}
resource "databricks_ip_access_list" "allow_corp" {
list_type = "ALLOW" # an ALLOW list flips to default-deny
ip_addresses = ["203.0.113.0/24"] # block lists win, evaluated first
}
# Item 5.2 — cluster policy: block legacy "No Isolation Shared"
# data_security_mode allowlist: ["USER_ISOLATION","SINGLE_USER"] # UC-compliant modes only
-- Item 6.1 — who changed permissions / failed to log in (Public Preview table; verify)
SELECT event_time, user_identity.email, action_name, source_ip_address
FROM system.access.audit
WHERE event_date >= current_date() - INTERVAL 7 DAYS
AND (action_name ILIKE '%Permission%' OR action_name ILIKE '%login%');
Portal: IP access lists = Account Console → Settings → Security → IP access lists; MFA is enforced in Entra ID Conditional Access (not a Databricks toggle).
The five whiteboard answers an SA gives cold. Switch the diagram between scenarios — each highlights the door(s) in play and the control that locks it. The golden rule for all five: trace the packet, name the control at each hop, state the trade-off, and know what breaks.
| Dimension | Service Endpoint | Private Endpoint |
|---|---|---|
| What it is | Subnet "tag" routing to a service over the backbone | NIC with a private IP mapped to one service |
| Storage FQDN resolves to | Public IP (firewall trusts the subnet) | Private IP (via privatelink.dfs.core.windows.net) |
| Cost | Free | Per-hour + per-GB |
| On-prem / cross-VNet reach | No | Yes |
| Serverless equivalent | NCC default rules expose SE subnet IDs | NCC private endpoint (dfs/blob) |
# Databricks CLI (account admin). dfs = ADLS data; blob = model artifacts (you may need both).
databricks account network-connectivity create-network-connectivity-configuration \
--json '{"name":"ncc-eastus","region":"eastus"}'
databricks account network-connectivity create-private-endpoint-rule <NCC_ID> \
--json '{"resource_id":".../storageAccounts/<ADLS>","group_id":"dfs"}'
# -> APPROVE on the storage account: Portal -> Storage -> Networking -> Private endpoint connections.
# Rule status: PENDING -> ESTABLISHED. Quotas: 10 NCCs/region, 100 PEs/region, 50 workspaces/NCC.
Conflating SCC and Private Link (SCC = no public IP/no inbound; PL = no public hop — say both). "Just whitelist the serverless IPs" (they're dynamic — it's NCC). Routing the SCC relay through the firewall (needless hop). Quoting Preview as GA (inbound PL for performance-intensive services is Preview — verify per region).
Start free, step up only when mandated. SCC + VNet injection (②) and storage firewall + Service Endpoint (③) cost nothing and are backbone-private. Add Private Link / NCC PEs / firewall DEP / CMK only when a regulator demands no public-IP hop or on-prem reach. Premium + Unity-Catalog-on-ADLS is the non-negotiable baseline; the IP-exhaustion layout applies to every design.
| Customer asks… | Architect answers… |
|---|---|
| "Walk me through how a query reaches our private storage without touching the internet." | Hop-by-hop: front-end PE → SSO via web-auth PE → SCC outbound + back-end PL → UC-governed ADLS via storage PE → any other egress via Azure Firewall FQDN allowlist. |
| "Does any traffic ever touch the public internet?" | Front/back-end Private Link + NCC PEs + storage firewall. SCC alone is backbone-but-public-IP, so "no public hop" is true only once back-end PL is on. |
| "Can we get a stable egress IP for our allowlist?" | Azure NAT Gateway for classic. Serverless has no static IP — use NCC, not an IP. |
| "How do we stop a compromised notebook from exfiltrating data?" | UDR 0.0.0.0/0 → Azure Firewall FQDN allowlist (DEP) + a serverless egress/network policy (default-deny). |
| "Service Endpoint or Private Endpoint for our ADLS?" | Default to Service Endpoints (free, backbone). Private Endpoints only when "no public IP, ever" or on-prem/cross-VNet reach is mandated. |
| "Can we start Simplified and move to full DEP later?" | Yes, but folding egress into the workspace VNet makes the firewall retrofit harder — plan the transit VNet now if DEP is on the roadmap. |
| "What needs Premium, and what's still Preview?" | PL / CMK / CSP / IP ACLs / audit delivery = Premium; inbound PL for performance-intensive services = Public Preview — verify per region. |
The shared browser_authentication host workspace was deleted/changed.First check: does it still exist and does *.pl-auth.azuredatabricks.net resolve to the PE private IP?
Custom/on-prem DNS isn't forwarding the zone.First check: spoke DNS conditional-forwards *.privatelink.azuredatabricks.net to Azure DNS.
Container subnet at the ceiling on autoscale.First check: prefix vs node count against 2^(32−n) − 5; CIDR is immutable.
Storage firewall on, allow rule missing.First check: storage Networking blade — is the SE subnet or the PE in the allow rules with default Deny?
NCC PE rule never approved.First check: rule status PENDING (approve on the storage account) + dfs vs blob group ID.
FQDNs not allowed, or SCC forced through the firewall.First check: application rules for the Databricks FQDNs; SCC/back-end-PL should NOT route through it.