Skip to content

Commit 9c3c8e9

Browse files
authored
Databricks on Azure with PrivateLink - Simplified deployment (#1977)
1 parent 9aa654b commit 9c3c8e9

File tree

2 files changed

+310
-0
lines changed

2 files changed

+310
-0
lines changed
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
---
2+
page_title: "Provisioning Databricks on Azure with Private Link - Simple deployment"
3+
---
4+
5+
# Deploying pre-requisite resources and enabling Private Link connections
6+
7+
-> **Note** This guide assumes that connectivity from the on-premises user environment is already configured using ExpressRoute or a VPN gateway connection.
8+
9+
Databricks Private Link support enables private connectivity between users and their Databricks workspaces and between clusters on the data plane and core services on the control plane within the Databricks workspace infrastructure.
10+
11+
You can use Terraform to deploy the underlying cloud resources and the private access settings resources automatically, using a programmatic approach.
12+
13+
14+
This guide covers a [simple deployment](https://learn.microsoft.com/en-us/azure/databricks/administration-guide/cloud-configurations/azure/private-link-simplified) to configure Azure Databricks with Private Link:
15+
* No separate VNet separates user access from the VNet that you use for your compute resources in the Classic data plane
16+
* A transit subnet in the data plane VNet is used for user access
17+
* Only a single private endpoint is used for both front-end and back-end connectivity.
18+
* A separate private endpoint is used for web authentication
19+
* The same Databricks workspace is used for web authentication traffic but Databricks strongly recommends creating a separate workspace called a private web auth workspace for each region to host the web auth private network settings.
20+
21+
![Private Link backend](https://github.com/databricks/terraform-provider-databricks/raw/master/docs/images/azure-private-link-simplified.png)
22+
23+
This guide uses the following variables:
24+
25+
- `cidr`: The CIDR for the Azure Vnet
26+
- `rg_name`: The name of the existing resource group
27+
- `location`: The location for Azure resources
28+
29+
This guide is provided as-is and you can use it as the basis for your custom Terraform module.
30+
31+
To get started with Azure Private Link integration, this guide takes you through the following high-level steps:
32+
33+
- Initialize the required providers
34+
- Configure Azure objects
35+
- Deploy an Azure Vnet with the following subnets:
36+
- Public and private subnets for Azure Databricks workspace
37+
- Private Link subnet that will contain the following private endpoints:
38+
- Frontend / Backend private endpoint
39+
- Web_auth private endpoint
40+
- Configure the private DNS zone in order to add:
41+
- DNS A record to map connection for workspace access
42+
- DNS A record(s) for web_auth
43+
- Workspace Creation
44+
45+
## Provider initialization
46+
47+
Initialize provider
48+
49+
```hcl
50+
terraform {
51+
required_providers {
52+
databricks = {
53+
source = "databricks/databricks"
54+
}
55+
azurerm = {
56+
source = "hashicorp/azurerm"
57+
version = ">=3.43.0"
58+
}
59+
}
60+
}
61+
62+
provider "azurerm" {
63+
features {}
64+
}
65+
```
66+
67+
Define the required variables
68+
69+
```hcl
70+
variable "cidr" {
71+
type = string
72+
}
73+
74+
variable "rg_name" {
75+
type = string
76+
}
77+
78+
variable "location" {
79+
type = string
80+
}
81+
82+
data "azurerm_client_config" "current" {
83+
}
84+
85+
data "external" "me" {
86+
program = ["az", "account", "show", "--query", "user"]
87+
}
88+
89+
locals {
90+
prefix = "abd-pl"
91+
tags = {
92+
Environment = "Demo"
93+
Owner = lookup(data.external.me.result, "name")
94+
}
95+
}
96+
```
97+
98+
## Configure network
99+
100+
### Deploy Azure vnet and subnets
101+
102+
Create a new Azure VNet, the required subnets and associated security groups:
103+
104+
```hcl
105+
resource "azurerm_virtual_network" "this" {
106+
name = "${local.prefix}-vnet"
107+
location = var.location
108+
resource_group_name = var.rg_name
109+
address_space = [var.cidr]
110+
tags = local.tags
111+
}
112+
113+
resource "azurerm_network_security_group" "this" {
114+
name = "${local.prefix}-nsg"
115+
location = var.location
116+
resource_group_name = var.rg_name
117+
tags = local.tags
118+
}
119+
120+
resource "azurerm_network_security_rule" "aad" {
121+
name = "AllowAAD"
122+
priority = 200
123+
direction = "Outbound"
124+
access = "Allow"
125+
protocol = "Tcp"
126+
source_port_range = "*"
127+
destination_port_range = "443"
128+
source_address_prefix = "VirtualNetwork"
129+
destination_address_prefix = "AzureActiveDirectory"
130+
resource_group_name = var.rg_name
131+
network_security_group_name = azurerm_network_security_group.this.name
132+
}
133+
134+
resource "azurerm_network_security_rule" "azfrontdoor" {
135+
name = "AllowAzureFrontDoor"
136+
priority = 201
137+
direction = "Outbound"
138+
access = "Allow"
139+
protocol = "Tcp"
140+
source_port_range = "*"
141+
destination_port_range = "443"
142+
source_address_prefix = "VirtualNetwork"
143+
destination_address_prefix = "AzureFrontDoor.Frontend"
144+
resource_group_name = var.rg_name
145+
network_security_group_name = azurerm_network_security_group.this.name
146+
}
147+
148+
resource "azurerm_subnet" "public" {
149+
name = "${local.prefix}-public"
150+
resource_group_name = var.rg_name
151+
virtual_network_name = azurerm_virtual_network.this.name
152+
address_prefixes = [cidrsubnet(var.cidr, 3, 0)]
153+
154+
delegation {
155+
name = "databricks"
156+
service_delegation {
157+
name = "Microsoft.Databricks/workspaces"
158+
actions = [
159+
"Microsoft.Network/virtualNetworks/subnets/join/action",
160+
"Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
161+
"Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"]
162+
}
163+
}
164+
}
165+
166+
resource "azurerm_subnet_network_security_group_association" "public" {
167+
subnet_id = azurerm_subnet.public.id
168+
network_security_group_id = azurerm_network_security_group.this.id
169+
}
170+
171+
variable "private_subnet_endpoints" {
172+
default = []
173+
}
174+
175+
resource "azurerm_subnet" "private" {
176+
name = "${local.prefix}-private"
177+
resource_group_name = var.rg_name
178+
virtual_network_name = azurerm_virtual_network.this.name
179+
address_prefixes = [cidrsubnet(var.cidr, 3, 1)]
180+
181+
enforce_private_link_endpoint_network_policies = true
182+
enforce_private_link_service_network_policies = true
183+
184+
delegation {
185+
name = "databricks"
186+
service_delegation {
187+
name = "Microsoft.Databricks/workspaces"
188+
actions = [
189+
"Microsoft.Network/virtualNetworks/subnets/join/action",
190+
"Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
191+
"Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"]
192+
}
193+
}
194+
195+
service_endpoints = var.private_subnet_endpoints
196+
}
197+
198+
resource "azurerm_subnet_network_security_group_association" "private" {
199+
subnet_id = azurerm_subnet.private.id
200+
network_security_group_id = azurerm_network_security_group.this.id
201+
}
202+
203+
204+
resource "azurerm_subnet" "plsubnet" {
205+
name = "${local.prefix}-privatelink"
206+
resource_group_name = var.rg_name
207+
virtual_network_name = azurerm_virtual_network.this.name
208+
address_prefixes = [cidrsubnet(var.cidr, 3, 2)]
209+
enforce_private_link_endpoint_network_policies = true
210+
}
211+
212+
```
213+
214+
### Deploy Azure private endpoints
215+
216+
#### Frontend / Backend private endpoint
217+
218+
Create a private endpoint with sub resource **databricks_ui_api**:
219+
220+
221+
```hcl
222+
resource "azurerm_private_endpoint" "uiapi" {
223+
name = "uiapipvtendpoint"
224+
location = var.location
225+
resource_group_name = var.rg_name
226+
subnet_id = azurerm_subnet.plsubnet.id
227+
228+
private_service_connection {
229+
name = "ple-${var.workspace_prefix}-uiapi"
230+
private_connection_resource_id = azurerm_databricks_workspace.this.id
231+
is_manual_connection = false
232+
subresource_names = ["databricks_ui_api"]
233+
}
234+
235+
private_dns_zone_group {
236+
name = "private-dns-zone-uiapi"
237+
private_dns_zone_ids = [azurerm_private_dns_zone.dnsuiapi.id]
238+
}
239+
}
240+
241+
resource "azurerm_private_dns_zone" "dnsuiapi" {
242+
name = "privatelink.azuredatabricks.net"
243+
resource_group_name = var.rg_name
244+
}
245+
246+
resource "azurerm_private_dns_zone_virtual_network_link" "uiapidnszonevnetlink" {
247+
name = "uiapispokevnetconnection"
248+
resource_group_name = var.rg_name
249+
private_dns_zone_name = azurerm_private_dns_zone.dnsuiapi.name
250+
virtual_network_id = azurerm_virtual_network.this.id // connect to spoke vnet
251+
}
252+
```
253+
254+
#### Web auth private endpoint
255+
256+
Create a private endpoint with sub resource **browser_authentication**:
257+
258+
```hcl
259+
resource "azurerm_private_endpoint" "auth" {
260+
name = "aadauthpvtendpoint"
261+
location = var.location
262+
resource_group_name = var.rg_name
263+
subnet_id = azurerm_subnet.plsubnet.id
264+
265+
private_service_connection {
266+
name = "ple-${var.workspace_prefix}-auth"
267+
private_connection_resource_id = azurerm_databricks_workspace.this.id
268+
is_manual_connection = false
269+
subresource_names = ["browser_authentication"]
270+
}
271+
272+
private_dns_zone_group {
273+
name = "private-dns-zone-auth"
274+
private_dns_zone_ids = [azurerm_private_dns_zone.dnsdpcp.id]
275+
}
276+
}
277+
```
278+
279+
## Configure workspace
280+
281+
Deploy an Azure Databricks workspace
282+
283+
```hcl
284+
resource "azurerm_databricks_workspace" "this" {
285+
name = "${local.prefix}-workspace"
286+
resource_group_name = var.rg_name
287+
location = var.location
288+
sku = "premium"
289+
tags = local.tags
290+
public_network_access_enabled = false
291+
network_security_group_rules_required = "NoAzureDatabricksRules"
292+
customer_managed_key_enabled = true
293+
custom_parameters {
294+
no_public_ip = true
295+
virtual_network_id = azurerm_virtual_network.this.id
296+
private_subnet_name = azurerm_subnet.private.name
297+
public_subnet_name = azurerm_subnet.public.name
298+
public_subnet_network_security_group_association_id = azurerm_subnet_network_security_group_association.public.id
299+
private_subnet_network_security_group_association_id = azurerm_subnet_network_security_group_association.private.id
300+
storage_account_name = "dbfs"
301+
}
302+
303+
depends_on = [
304+
azurerm_subnet_network_security_group_association.public,
305+
azurerm_subnet_network_security_group_association.private
306+
]
307+
}
308+
```
309+
310+
-> **Note** The public network access to the workspace is disabled. You can access the workspace only through the private connectivity to the on-premises user environment. For testing purposes, you can deploy an Azure VM in the same vnet in order to test the frontend connectivity.
112 KB
Loading

0 commit comments

Comments
 (0)