Network Guide: Traffic flows, security groups, and encryption layers visualized.
π 2 Encryption Layers (Independent):
βββ S3 Bucket Encryption (enable_encryption)
βββ Workspace CMK (enable_workspace_cmk)
π‘οΈ 2 Security Groups:
βββ Workspace SG (cluster nodes)
βββ VPCE SG (VPC endpoints)
π Regional VPC Endpoints (Cost Optimized):
βββ S3 Gateway Endpoint (FREE)
βββ STS Interface Endpoint
βββ Kinesis Interface Endpoint
%%{init: {'theme': 'base'}}%%
sequenceDiagram
autonumber
participant C as Cluster Node<br/>10.0.1.5
participant DNS as VPC DNS<br/>10.0.0.2
participant RT as Route Table
participant SG as Security Group
participant VPCE as VPC Endpoint<br/>10.0.3.5
participant DB as Databricks<br/>Control Plane
C->>DNS: Resolve dbc-*.cloud.databricks.com
DNS-->>C: Returns 10.0.3.5 (private IP)
C->>RT: Lookup route for 10.0.3.5
RT-->>C: Use "local" route (VPC-internal)
C->>SG: Check egress rule TCP 8443
SG-->>C: Allow (rule: TCP 8443-8451 β vpce_sg)
C->>VPCE: Send request to 10.0.3.5:8443
VPCE->>DB: Forward via Private Link
DB-->>VPCE: Response
VPCE-->>C: Response
Key Points:
Docs: Private Link Architecture
%%{init: {'theme': 'base'}}%%
flowchart LR
C["Cluster Node"] -->|1. S3 API call| RT["Route Table"]
RT -->|2. Match prefix list| GW["S3 Gateway<br/>Endpoint"]
GW -->|3. VPC-internal| S3["S3 Bucket"]
S3 -->|4. If encrypted| KMS["KMS Key<br/>Decrypt"]
KMS -->|5. Decrypted data| S3
S3 -->|6. Response| C
style GW fill:#569A31
style KMS fill:#FF9900
Always FREE - No data transfer charges!
Attached To: EC2 instances in private subnets
Rule 1: Cluster to Cluster Communication
βββ Protocol: TCP
βββ Port Range: 0-65535
βββ Destination: self (workspace_sg)
βββ Purpose: Spark worker communication
Rule 2: Cluster to Cluster UDP
βββ Protocol: UDP
βββ Port Range: 0-65535
βββ Destination: self (workspace_sg)
βββ Purpose: Spark shuffle operations
Rule 3: Control Plane API (Private Link)
βββ Protocol: TCP
βββ Port Range: 8443-8451
βββ Destination: vpce_sg
βββ Purpose: Workspace REST API via VPCE
Rule 4: Secure Cluster Connectivity (Private Link)
βββ Protocol: TCP
βββ Port Range: 6666
βββ Destination: vpce_sg
βββ Purpose: Relay/SCC via VPCE
Rule 5: FIPS Encryption (Optional)
βββ Protocol: TCP
βββ Port Range: 2443
βββ Destination: 0.0.0.0/0
βββ Purpose: FIPS encryption for compliance security profile
Rule 6: Public Internet (if needed)
βββ Protocol: TCP
βββ Port Range: 443, 53
βββ Destination: 0.0.0.0/0
βββ Purpose: Maven, PyPI, DNS
Rule 1: TCP from Clusters
βββ Protocol: TCP
βββ Port Range: 0-65535
βββ Source: self (workspace_sg)
βββ Purpose: Allow worker-to-worker
Rule 2: UDP from Clusters
βββ Protocol: UDP
βββ Port Range: 0-65535
βββ Source: self (workspace_sg)
βββ Purpose: Allow shuffle traffic
Docs: Security Groups
Attached To: Databricks VPC endpoints (workspace + relay)
Rule 1: Allow All Outbound
βββ Protocol: All
βββ Port Range: All
βββ Destination: 0.0.0.0/0
βββ Purpose: VPCE to Databricks
Rule 1: From Workspace SG (8443-8451)
βββ Protocol: TCP
βββ Port Range: 8443-8451
βββ Source: workspace_sg
βββ Purpose: Allow API calls
Rule 2: From Workspace SG (6666)
βββ Protocol: TCP
βββ Port Range: 6666
βββ Source: workspace_sg
βββ Purpose: Allow SCC
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e1e1e1'}}}%%
flowchart TD
subgraph "Layer 1: S3 Bucket Encryption"
KMS1["KMS Key<br/>S3 Encryption"]
S3["S3 Buckets<br/>β’ DBFS Root<br/>β’ UC Metastore<br/>β’ UC External"]
KMS1 -->|Encrypts| S3
end
subgraph "Layer 2: Workspace CMK"
KMS2["KMS Key<br/>Workspace Storage"]
DBFS["DBFS Root<br/>at-rest"]
EBS["EBS Volumes<br/>cluster storage"]
MS["Managed Services<br/>notebooks, jobs"]
KMS2 -->|Encrypts| DBFS
KMS2 -->|Encrypts| EBS
KMS2 -->|Encrypts| MS
end
style KMS1 fill:#569A31
style KMS2 fill:#FF9900
Independent Configuration:
enable_encryption = true β Layer 1 onlyenable_workspace_cmk = true β Layer 2 onlyDocs: Customer-Managed Keys
Layer 1 - S3 Bucket Encryption:
βββ When: enable_encryption = true
βββ Key Created: aws_kms_key.databricks
βββ Encrypts: All S3 buckets (SSE-KMS)
βββ Permissions: UC roles get KMS permissions
Layer 2 - Workspace CMK:
βββ When: enable_workspace_cmk = true
βββ Key Created: aws_kms_key.workspace_storage
βββ Encrypts: DBFS root, EBS, Managed Services
βββ Permissions: In KMS key policy (Databricks service principal)
AWS Automatic Rotation (Enabled by default):
βββ Rotates underlying key material annually
βββ ARN remains the same
βββ Applies to both Layer 1 and Layer 2 keys
βββ No action required
Manual Rotation to Different Key:
βββ Managed Services CMK: β
Supported
βββ Storage CMK (DBFS/EBS): β Not supported
βββ S3 Bucket keys: β
Update S3 bucket config
Docs: Key Rotation
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e1e1e1'}}}%%
flowchart TD
START["enable_private_link"] -->|true| PL["Private Link Path"]
START -->|false| PUB["Public Internet Path"]
PL --> PLDNS["DNS returns<br/>private IP 10.0.3.x"]
PLDNS --> PLVPCE["Traffic via<br/>VPC Endpoint"]
PLVPCE --> PLDB["Databricks<br/>Private Link"]
PUB --> PUBDNS["DNS returns<br/>public IP"]
PUBDNS --> NAT["Traffic via<br/>NAT Gateway"]
NAT --> IGW["Internet<br/>Gateway"]
IGW --> PUBDB["Databricks<br/>Public Internet"]
style PL fill:#569A31
style PUB fill:#FF9900
Comparison:
| Aspect | Private Link (true) | Public Internet (false) |
|---|---|---|
| DNS Resolution | Private IP 10.0.3.x | Public IP |
| Traffic Path | VPC Endpoint β Private Link | NAT β Internet |
| Data Egress Charges | Lower | Higher |
| Security | No internet exposure | Internet-routable |
| Cost | VPCE charges ~$7.2/day | NAT charges variable |
Databricks Control Plane:
βββ 8443-8451: REST API, Unity Catalog, WebSockets
βββ 6666: Secure Cluster Connectivity (ONLY with Private Link)
βββ 2443: FIPS encryption (ONLY if compliance security profile enabled)
AWS Services:
βββ 443: S3 Gateway, STS, Kinesis (via regional VPC endpoints)
βββ 3306: MySQL metastore (LEGACY - NOT USED with Unity Catalog)
Public Internet (via NAT Gateway):
βββ 443: Maven Central, PyPI, Docker registries
βββ 53: DNS resolution
Why 9 ports (8443-8451)?
8443: Primary workspace API
8444-8451: WebSocket connections, streaming, long-running jobs
All 9 ports required for full functionality!
Warning: Restricting to only 8443 will break WebSocket features
Docs: Port Requirements
%%{init: {'theme': 'base'}}%%
sequenceDiagram
participant C as Cluster
participant DNS as VPC DNS
participant VPCE as VPC Endpoint
Note over VPCE: private_dns_enabled = true
C->>DNS: Query dbc-abc123.cloud.databricks.com
DNS->>VPCE: Check VPCE private hosted zone
VPCE-->>DNS: Return 10.0.3.5 (private IP)
DNS-->>C: 10.0.3.5
Note over C: Traffic stays in VPC!
Key Setting: private_dns_enabled = true on VPC endpoint
Without Private DNS:
β Already Configured: This deployment uses regional VPC endpoints for all AWS services:
com.amazonaws.${region}.s3 (Gateway endpoint - FREE)com.amazonaws.${region}.sts (Interface endpoint)com.amazonaws.${region}.kinesis-streams (Interface endpoint)β Benefits:
Docs: Configure Regional Endpoints
While VPC endpoints handle AWS service traffic automatically, you may optionally configure Spark to use regional S3/STS endpoints explicitly. This is useful for enforcing data residency requirements.
β οΈ Important: This configuration prevents cross-region S3 access. Only apply if all your S3 buckets are in the same region.
Add to the beginning of your notebook:
Scala:
%scala
spark.conf.set("fs.s3a.stsAssumeRole.stsEndpoint", "https://sts.<region>.amazonaws.com")
spark.conf.set("fs.s3a.endpoint", "https://s3.<region>.amazonaws.com")
Python:
%python
spark.conf.set("fs.s3a.stsAssumeRole.stsEndpoint", "https://sts.<region>.amazonaws.com")
spark.conf.set("fs.s3a.endpoint", "https://s3.<region>.amazonaws.com")
Replace <region> with your AWS region (e.g., us-west-2).
Add to cluster Spark config (Cluster β Edit β Advanced Options β Spark):
spark.hadoop.fs.s3a.endpoint https://s3.<region>.amazonaws.com
spark.hadoop.fs.s3a.stsAssumeRole.stsEndpoint https://sts.<region>.amazonaws.com
Create or update your cluster policy to enforce regional endpoints for all clusters:
{
"spark_conf.fs.s3a.endpoint": {
"type": "fixed",
"value": "https://s3.<region>.amazonaws.com"
},
"spark_conf.fs.s3a.stsAssumeRole.stsEndpoint": {
"type": "fixed",
"value": "https://sts.<region>.amazonaws.com"
}
}
%%{init: {'theme': 'base'}}%%
sequenceDiagram
participant Cluster as Cluster Node
participant DNS as VPC DNS
participant VPCE as VPC Endpoint<br/>(Regional)
participant S3 as S3 Service<br/>(Regional)
Note over Cluster,S3: Without Spark Config (Default)
Cluster->>DNS: Resolve s3.amazonaws.com (global)
DNS-->>Cluster: Private IP (VPC endpoint)
Cluster->>VPCE: Request via VPC endpoint
VPCE->>S3: Regional service
S3-->>VPCE: Response
VPCE-->>Cluster: Response
Note over Cluster,S3: With Spark Regional Config
Cluster->>DNS: Resolve s3.<region>.amazonaws.com
DNS-->>Cluster: Private IP (VPC endpoint)
Cluster->>VPCE: Request via VPC endpoint
VPCE->>S3: Regional service (enforced)
S3-->>VPCE: Response (same region only)
VPCE-->>Cluster: Response
Key Differences:
Cause: S3 bucket is in a different region than the workspace Solution: Either move bucket to workspace region, or remove Spark regional config
Cause: Regional endpoint config blocks cross-region S3 access
Solution: Remove fs.s3a.endpoint and fs.s3a.stsAssumeRole.stsEndpoint from Spark config
Cause: Regional config enforces regional URLs only
Solution: Update S3 paths to use regional format: s3://bucket/path (Spark handles conversion)
Docs: Troubleshoot Regional Endpoints
β Network security understood β 04-QUICK-START.md - Deploy now!
β Need troubleshooting β 05-TROUBLESHOOTING.md - Common issues
Docs: Network Security