Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The folder `examples` contains the following Terraform implementation examples :
| Azure | ~~adb-external-hive-metastore~~ **REMOVED** | This example was removed in February 2026. External Hive metastore has been superseded by [Unity Catalog](https://docs.databricks.com/en/data-governance/unity-catalog/index.html). Use [adb-unity-catalog-basic-demo](examples/adb-unity-catalog-basic-demo/) instead. |
| Azure | [adb-kafka](examples/adb-kafka/) | ADB - single node kafka template |
| Azure | [adb-private-links](examples/adb-private-links/) | Azure Databricks Private Links |
| Azure | [adb-serverless-appgw-tls-transit](examples/adb-serverless-appgw-tls-transit/) | Serverless compute to a TLS service through an Application Gateway v2 TCP/TLS proxy and NCC private endpoint |
| Azure | [adb-squid-proxy](examples/adb-squid-proxy/) | ADB clusters with HTTP proxy |
| Azure | [adb-teradata](examples/adb-teradata/) | ADB with single VM Teradata integration |
| Azure | [adb-uc](examples/adb-uc/) | ADB Unity Catalog Process |
Expand Down Expand Up @@ -77,6 +78,7 @@ The folder `modules` contains the following Terraform modules :
| Azure | [adb-with-private-link-standard](modules/adb-with-private-link-standard/) | Provisioning Databricks on Azure with Private Link - Standard deployment |
| Azure | [adb-exfiltration-protection](modules/adb-exfiltration-protection/) | A sample implementation of [Data Exfiltration Protection](https://www.databricks.com/blog/2020/03/27/data-exfiltration-protection-with-azure-databricks.html) |
| Azure | [adb-with-private-links-exfiltration-protection](modules/adb-with-private-links-exfiltration-protection/) | Provisioning Databricks on Azure with Private Link and [Data Exfiltration Protection](https://www.databricks.com/blog/2020/03/27/data-exfiltration-protection-with-azure-databricks.html) |
| Azure | [adb-serverless-appgw-tls-transit](modules/adb-serverless-appgw-tls-transit/) | Serverless compute to a TLS service through an Application Gateway v2 TCP/TLS proxy and NCC private endpoint |
| Azure | [adb-overwatch-regional-config](modules/adb-overwatch-regional-config/) | Overwatch regional configuration on Azure |
| Azure | [adb-overwatch-mws-config](modules/adb-overwatch-mws-config/) | Overwatch multi-workspace deployment on Azure |
| Azure | [adb-overwatch-main-ws](modules/adb-overwatch-main-ws/) | Main Overwatch workspace deployment |
Expand Down
7 changes: 7 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: docs test_docs

docs:
terraform-docs -c ../../.terraform-docs.yml .

test_docs:
terraform-docs -c ../../.terraform-docs.yml --output-check .
84 changes: 84 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Serverless compute to a TLS service through Application Gateway v2

This example deploys the [`adb-serverless-appgw-tls-transit`](../../modules/adb-serverless-appgw-tls-transit) module. It connects Databricks Serverless compute to a customer-managed TLS-over-TCP service (for example, Confluent Cloud Kafka) through an Azure Application Gateway v2 TCP proxy and the Databricks Network Connectivity Configuration (NCC) service.

```text
Databricks Serverless -> NCC private endpoint -> Application Gateway v2
-> TLS backend
```

The Application Gateway passes encrypted TCP/TLS traffic through; it does not terminate TLS. The target service must be reachable from the transit VNet using a private endpoint, VNet peering, or another private route. This example accepts backend IPv4 addresses or FQDNs and does not provision the target service.

## Prerequisites

* A Premium Azure Databricks account and account-admin permissions.
* An Azure subscription and permissions to create a VNet, subnets, NSG, public IP, and Application Gateway.
* Azure CLI authenticated as a Databricks account admin. The module uses the documented Network Connectivity Configurations REST API because Application Gateway rules require `resource_id`, `group_id`, and `domain_names` together.
* A TLS-over-TCP backend reachable from the transit VNet and the FQDNs that Serverless clients dial. For Kafka, include the bootstrap FQDN and the broker names returned in metadata.

## How to use

1. Update `terraform.tfvars` with your Azure, Databricks, backend, and DNS values.
2. Run `terraform init`.
3. Run `terraform plan` and `terraform apply`.
4. Approve the pending private endpoint connection on the Application Gateway, unless `auto_approve_private_endpoint` is enabled and the Azure CLI identity can approve it.
5. Wait until the NCC private endpoint rule is `ESTABLISHED`, restart Serverless compute, and test the TLS service.

The Standard_v2 SKU currently requires a public IP resource for gateway management. The example creates that resource but does not bind a listener to the public frontend. Databricks traffic uses the private frontend exposed through Application Gateway Private Link. If your subscription has Azure network isolation enabled and no public IP is required, adjust the Application Gateway definition accordingly.

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
| ---- | ------- |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_azapi"></a> [azapi](#requirement\_azapi) | 2.0.1 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.31.0 |
| <a name="requirement_databricks"></a> [databricks](#requirement\_databricks) | >=1.81.1 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >=3.2.0 |
| <a name="requirement_time"></a> [time](#requirement\_time) | >=0.9.0 |

## Providers

No providers.

## Modules

| Name | Source | Version |
| ---- | ------ | ------- |
| <a name="module_adb-serverless-appgw-tls-transit"></a> [adb-serverless-appgw-tls-transit](#module\_adb-serverless-appgw-tls-transit) | ../../modules/adb-serverless-appgw-tls-transit | n/a |

## Resources

No resources.

## Inputs

| Name | Description | Type | Default | Required |
| ---- | ----------- | ---- | ------- | :------: |
| <a name="input_azure_region"></a> [azure\_region](#input\_azure\_region) | Azure region short name. Must match the workspace and NCC region. | `string` | n/a | yes |
| <a name="input_azure_subscription_id"></a> [azure\_subscription\_id](#input\_azure\_subscription\_id) | Azure subscription ID to deploy into. | `string` | n/a | yes |
| <a name="input_databricks_account_id"></a> [databricks\_account\_id](#input\_databricks\_account\_id) | Databricks account ID (UUID). | `string` | n/a | yes |
| <a name="input_databricks_workspace_id"></a> [databricks\_workspace\_id](#input\_databricks\_workspace\_id) | Databricks workspace ID to bind to the NCC. | `string` | n/a | yes |
| <a name="input_serverless_domain_names"></a> [serverless\_domain\_names](#input\_serverless\_domain\_names) | FQDNs that serverless clients dial. The NCC rule supports at most 10 names. | `list(string)` | n/a | yes |
| <a name="input_appgw_capacity"></a> [appgw\_capacity](#input\_appgw\_capacity) | Fixed Standard\_v2 Application Gateway instance capacity. | `number` | `2` | no |
| <a name="input_appgw_name"></a> [appgw\_name](#input\_appgw\_name) | Application Gateway name. | `string` | `"appgw-serverless-transit"` | no |
| <a name="input_auto_approve_private_endpoint"></a> [auto\_approve\_private\_endpoint](#input\_auto\_approve\_private\_endpoint) | Attempt to approve the Databricks-created private endpoint with Azure CLI. | `bool` | `false` | no |
| <a name="input_backend_addresses"></a> [backend\_addresses](#input\_backend\_addresses) | IPv4 addresses of TLS backends reachable from the transit VNet. | `list(string)` | `[]` | no |
| <a name="input_backend_fqdns"></a> [backend\_fqdns](#input\_backend\_fqdns) | FQDNs of TLS backends reachable from the transit VNet. | `list(string)` | `[]` | no |
| <a name="input_backend_port"></a> [backend\_port](#input\_backend\_port) | TCP/TLS port used by the backend. Defaults to listener\_port. | `number` | `null` | no |
| <a name="input_databricks_host"></a> [databricks\_host](#input\_databricks\_host) | Databricks account console host. | `string` | `"https://accounts.azuredatabricks.net"` | no |
| <a name="input_listener_port"></a> [listener\_port](#input\_listener\_port) | TCP/TLS port exposed by the Application Gateway. | `number` | `9092` | no |
| <a name="input_rg_name"></a> [rg\_name](#input\_rg\_name) | Resource group to create for the transit resources. | `string` | `"rg-appgw-tls-transit"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags applied to created resources. | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
| ---- | ----------- |
| <a name="output_appgw_frontend_config_name"></a> [appgw\_frontend\_config\_name](#output\_appgw\_frontend\_config\_name) | Frontend configuration name used as the NCC rule group\_id. |
| <a name="output_appgw_id"></a> [appgw\_id](#output\_appgw\_id) | Resource ID of the Application Gateway. |
| <a name="output_ncc_id"></a> [ncc\_id](#output\_ncc\_id) | Databricks NCC ID. |
| <a name="output_serverless_domain_names"></a> [serverless\_domain\_names](#output\_serverless\_domain\_names) | FQDNs registered in the NCC private endpoint rule. |
| <a name="output_transit_vnet_id"></a> [transit\_vnet\_id](#output\_transit\_vnet\_id) | Transit VNet ID. Peer the target service network here or place a private endpoint in it. |
<!-- END_TF_DOCS -->
29 changes: 29 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module "adb-serverless-appgw-tls-transit" {
source = "../../modules/adb-serverless-appgw-tls-transit"

providers = {
azurerm = azurerm
azapi = azapi
databricks = databricks.accounts
null = null
time = time
}

azure_subscription_id = var.azure_subscription_id
azure_region = var.azure_region
rg_name = var.rg_name
appgw_name = var.appgw_name
appgw_capacity = var.appgw_capacity
databricks_host = var.databricks_host
databricks_account_id = var.databricks_account_id
databricks_workspace_id = var.databricks_workspace_id

backend_addresses = var.backend_addresses
backend_fqdns = var.backend_fqdns
listener_port = var.listener_port
backend_port = var.backend_port
serverless_domain_names = var.serverless_domain_names
auto_approve_private_endpoint = var.auto_approve_private_endpoint

tags = var.tags
}
24 changes: 24 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "appgw_id" {
description = "Resource ID of the Application Gateway."
value = module.adb-serverless-appgw-tls-transit.appgw_id
}

output "appgw_frontend_config_name" {
description = "Frontend configuration name used as the NCC rule group_id."
value = module.adb-serverless-appgw-tls-transit.appgw_frontend_config_name
}

output "ncc_id" {
description = "Databricks NCC ID."
value = module.adb-serverless-appgw-tls-transit.ncc_id
}

output "serverless_domain_names" {
description = "FQDNs registered in the NCC private endpoint rule."
value = module.adb-serverless-appgw-tls-transit.serverless_domain_names
}

output "transit_vnet_id" {
description = "Transit VNet ID. Peer the target service network here or place a private endpoint in it."
value = module.adb-serverless-appgw-tls-transit.transit_vnet_id
}
41 changes: 41 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
terraform {
required_version = ">= 1.9.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.31.0"
}
azapi = {
source = "Azure/azapi"
version = "2.0.1"
}
databricks = {
source = "databricks/databricks"
version = ">=1.81.1"
}
null = {
source = "hashicorp/null"
version = ">=3.2.0"
}
time = {
source = "hashicorp/time"
version = ">=0.9.0"
}
}
}

provider "azurerm" {
subscription_id = var.azure_subscription_id
features {}
}

provider "azapi" {
subscription_id = var.azure_subscription_id
}

provider "databricks" {
alias = "accounts"
host = var.databricks_host
account_id = var.databricks_account_id
}
32 changes: 32 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
azure_subscription_id = "00000000-0000-0000-0000-000000000000"
azure_region = "australiaeast"
rg_name = "rg-appgw-tls-transit"

appgw_name = "appgw-serverless-transit"
appgw_capacity = 2

databricks_host = "https://accounts.azuredatabricks.net"
databricks_account_id = "00000000-0000-0000-0000-000000000000"
databricks_workspace_id = "1234567890123456"

# Use either backend_addresses (IP addresses) or backend_fqdns (DNS names).
# The target must be reachable from the transit VNet.
backend_addresses = ["10.230.3.10"]
backend_fqdns = []

# Include the bootstrap name and any names returned by Kafka broker metadata.
serverless_domain_names = [
"lkc-xxxxx.<network-id>.australiaeast.azure.confluent.cloud",
"*.<network-id>.australiaeast.azure.confluent.cloud",
]

listener_port = 9092
backend_port = null

# Leave false to approve the App Gateway private endpoint manually in Azure.
auto_approve_private_endpoint = false

tags = {
Environment = "dev"
Workload = "serverless-tls-privatelink"
}
84 changes: 84 additions & 0 deletions examples/adb-serverless-appgw-tls-transit/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
variable "azure_subscription_id" {
type = string
description = "Azure subscription ID to deploy into."
}

variable "azure_region" {
type = string
description = "Azure region short name. Must match the workspace and NCC region."
}

variable "rg_name" {
type = string
description = "Resource group to create for the transit resources."
default = "rg-appgw-tls-transit"
}

variable "appgw_name" {
type = string
description = "Application Gateway name."
default = "appgw-serverless-transit"
}

variable "appgw_capacity" {
type = number
description = "Fixed Standard_v2 Application Gateway instance capacity."
default = 2
}

variable "databricks_host" {
type = string
description = "Databricks account console host."
default = "https://accounts.azuredatabricks.net"
}

variable "databricks_account_id" {
type = string
description = "Databricks account ID (UUID)."
}

variable "databricks_workspace_id" {
type = string
description = "Databricks workspace ID to bind to the NCC."
}

variable "backend_addresses" {
type = list(string)
description = "IPv4 addresses of TLS backends reachable from the transit VNet."
default = []
}

variable "backend_fqdns" {
type = list(string)
description = "FQDNs of TLS backends reachable from the transit VNet."
default = []
}

variable "serverless_domain_names" {
type = list(string)
description = "FQDNs that serverless clients dial. The NCC rule supports at most 10 names."
}

variable "listener_port" {
type = number
description = "TCP/TLS port exposed by the Application Gateway."
default = 9092
}

variable "backend_port" {
type = number
description = "TCP/TLS port used by the backend. Defaults to listener_port."
default = null
}

variable "auto_approve_private_endpoint" {
type = bool
description = "Attempt to approve the Databricks-created private endpoint with Azure CLI."
default = false
}

variable "tags" {
type = map(string)
description = "Tags applied to created resources."
default = {}
}
7 changes: 7 additions & 0 deletions modules/adb-serverless-appgw-tls-transit/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: docs test_docs

docs:
terraform-docs -c ../../.terraform-docs.yml .

test_docs:
terraform-docs -c ../../.terraform-docs.yml --output-check .
Loading