Skip to content
Merged
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
3 changes: 2 additions & 1 deletion 5_analytics-bigdata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Costa Rica
[![GitHub](https://img.shields.io/badge/--181717?logo=github&logoColor=ffffff)](https://github.com/)
[brown9804](https://github.com/brown9804)

Last updated: 2026-02-09
Last updated: 2026-02-12

------------------------------------------

Expand All @@ -15,6 +15,7 @@ Last updated: 2026-02-09
## Templates available

- [Azure Data Factory](./data-factory)
- [Azure Databricks (Workspace)](./databricks)
- [Azure Synapse Analytics (Workspace)](./synapse-analytics)

<!-- START BADGE -->
Expand Down
87 changes: 87 additions & 0 deletions 5_analytics-bigdata/databricks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Terraform Template - Azure Databricks (Workspace)

Costa Rica

[![GitHub](https://img.shields.io/badge/--181717?logo=github&logoColor=ffffff)](https://github.com/)
[brown9804](https://github.com/brown9804)

Last updated: 2026-02-12

------------------------------------------

> This template contains Terraform configurations to create an Azure Databricks workspace.

> [!IMPORTANT]
>
> - Azure Databricks creates a **managed resource group** for service-managed infrastructure. You will typically see **two resource groups**: your main RG plus the Databricks-managed RG. This is expected behavior.
> - If you disable `append_random_suffix`, you may hit name collisions.

<div align="center">
<img width="650" alt="image" src="https://github.com/user-attachments/assets/5f4cf7a6-9317-4d34-adcf-c493297ab814" style="border: 2px solid #4CAF50; border-radius: 5px; padding: 5px;"/>
</div>

<div align="center">
<img width="650" alt="image" src="https://github.com/user-attachments/assets/90778a82-a56f-4b56-8673-66339073c746" style="border: 2px solid #4CAF50; border-radius: 5px; padding: 5px;"/>
</div>

<div align="center">
<img width="650" alt="image" src="https://github.com/user-attachments/assets/eb7c2c5c-2f1b-4bb1-8266-5e3093f28371" style="border: 2px solid #4CAF50; border-radius: 5px; padding: 5px;"/>
</div>

## File Descriptions

- **main.tf**: Creates/updates the Resource Group (idempotent ARM PUT) and the Databricks workspace.
- **variables.tf**: Defines input variables used in the Terraform configuration.
- **provider.tf**: Configures the AzureRM + AzAPI + Random providers.
- **terraform.tfvars**: Example values for variables.
- **outputs.tf**: Outputs such as the workspace ID and URL.

## Variables

| Variable Name | Description | Type | Example Value |
| --- | --- | --- | --- |
| `resource_group_name` | Resource Group name to deploy into (created if missing). | string | `"rg-analytics-dev"` |
| `location` | Azure region for the deployment. | string | `"eastus"` |
| `databricks_workspace_name` | Base workspace name. If suffix enabled, final is `<base>-<suffix>`. | string | `"dbw-analytics-dev"` |
| `sku` | Workspace SKU (`standard`, `premium`, `trial`). | string | `"standard"` |
| `managed_resource_group_name` | Optional base managed RG name. If omitted, Databricks auto-generates it. | string | `null` |
| `append_random_suffix` | Append random suffix to reduce name collisions. | bool | `true` |
| `random_suffix_length` | Length of the suffix when enabled. | number | `6` |
| `tags` | Tags applied to resources. | map(string) | `{ "env": "dev" }` |

## Usage

1. Authenticate:

```sh
az login
az account show
# If needed:
az account set --subscription "<subscription-id-or-name>"
```

2. Initialize:

```sh
terraform init -upgrade
```

3. Validate and plan:

```sh
terraform validate
terraform plan
```

4. Apply:

```sh
terraform apply -auto-approve
```

<!-- START BADGE -->
<div align="center">
<img src="https://img.shields.io/badge/Total%20views-1790-limegreen" alt="Total views">
<p>Refresh Date: 2026-02-12</p>
</div>
<!-- END BADGE -->
64 changes: 64 additions & 0 deletions 5_analytics-bigdata/databricks/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# main.tf
# Creates an Azure Databricks workspace.

data "azurerm_client_config" "current" {}

# Resource group creation is idempotent in ARM (PUT). This will create the RG if it doesn't exist,
# or update tags if it already exists.
resource "azapi_resource" "resource_group" {
type = "Microsoft.Resources/resourceGroups@2022-09-01"
name = var.resource_group_name
location = var.location
parent_id = "/subscriptions/${data.azurerm_client_config.current.subscription_id}"

body = jsonencode({
tags = var.tags
})

response_export_values = [
"id",
"name"
]
}

resource "random_string" "suffix" {
length = var.random_suffix_length
upper = false
special = false
numeric = true

keepers = {
resource_group_name = var.resource_group_name
location = var.location
workspace_base = var.databricks_workspace_name
sku = lower(var.sku)
managed_rg_base = coalesce(var.managed_resource_group_name, "rg-databricks-managed-${var.databricks_workspace_name}")
}
}

locals {
suffix = var.append_random_suffix ? random_string.suffix.result : ""

workspace_name = var.append_random_suffix ? "${var.databricks_workspace_name}-${local.suffix}" : var.databricks_workspace_name

managed_rg_name = (
var.managed_resource_group_name == null
? null
: (var.append_random_suffix ? "${var.managed_resource_group_name}-${local.suffix}" : var.managed_resource_group_name)
)
}

resource "azurerm_databricks_workspace" "ws" {
name = local.workspace_name
resource_group_name = var.resource_group_name
location = var.location
sku = lower(var.sku)

managed_resource_group_name = local.managed_rg_name

tags = var.tags

depends_on = [
azapi_resource.resource_group
]
}
21 changes: 21 additions & 0 deletions 5_analytics-bigdata/databricks/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# outputs.tf

output "resource_group_id" {
description = "The ID of the resource group."
value = azapi_resource.resource_group.id
}

output "databricks_workspace_id" {
description = "The resource ID of the Databricks workspace."
value = azurerm_databricks_workspace.ws.id
}

output "databricks_workspace_name" {
description = "The name of the Databricks workspace."
value = azurerm_databricks_workspace.ws.name
}

output "databricks_workspace_url" {
description = "The workspace URL of the Databricks workspace."
value = azurerm_databricks_workspace.ws.workspace_url
}
38 changes: 38 additions & 0 deletions 5_analytics-bigdata/databricks/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# provider.tf
# Provider configuration for Azure Databricks workspace deployment.

terraform {
required_version = ">= 1.8, < 2.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.116"
}

azapi = {
source = "Azure/azapi"
version = "~> 1.13"
}

random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}

provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}

# Uses the current Azure CLI context (az login + az account set)
skip_provider_registration = false
}

provider "azapi" {
# Uses the current Azure CLI context (az login + az account set)
}
21 changes: 21 additions & 0 deletions 5_analytics-bigdata/databricks/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource_group_name = "rg-analytics-dev"
location = "eastus"

# Databricks workspace names are unique within your subscription.
# This template appends a random suffix by default to reduce collisions.
databricks_workspace_name = "dbw-analytics-dev"

# Optional. If omitted, Databricks auto-generates the managed resource group name.
# managed_resource_group_name = "rg-databricks-managed-analytics-dev"

# SKU: standard | premium | trial
sku = "standard"

append_random_suffix = true
random_suffix_length = 6

tags = {
env = "dev"
area = "analytics-bigdata"
iac = "terraform"
}
84 changes: 84 additions & 0 deletions 5_analytics-bigdata/databricks/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# variables.tf

variable "resource_group_name" {
description = "The name of the Azure Resource Group to deploy into. This template will create the RG if it does not exist (idempotent ARM PUT)."
type = string

validation {
condition = length(trimspace(var.resource_group_name)) > 0
error_message = "resource_group_name must not be empty."
}
}

variable "location" {
description = "The Azure region where the Resource Group and Databricks workspace will be created."
type = string

validation {
condition = length(trimspace(var.location)) > 0
error_message = "location must not be empty."
}
}

variable "databricks_workspace_name" {
description = "Base name of the Azure Databricks workspace. If append_random_suffix is true, the final name will be '<base>-<suffix>'."
type = string

validation {
condition = (
length(trimspace(var.databricks_workspace_name)) > 0
&& can(regex("^[a-zA-Z0-9][a-zA-Z0-9-]*$", var.databricks_workspace_name))
)
error_message = "databricks_workspace_name must not be empty, start with alphanumeric, and contain only alphanumeric or '-'."
}
}

variable "sku" {
description = "Databricks workspace SKU."
type = string
default = "standard"

validation {
condition = contains(["standard", "premium", "trial"], lower(var.sku))
error_message = "sku must be one of: standard, premium, trial."
}
}

variable "managed_resource_group_name" {
description = "Optional base name of the Databricks managed resource group. If null/omitted, Databricks auto-generates it. If append_random_suffix is true, the final name will be '<base>-<suffix>'."
type = string
default = null

validation {
condition = (
var.managed_resource_group_name == null ? true : (
length(try(trimspace(var.managed_resource_group_name), "")) > 0
&& length(try(var.managed_resource_group_name, "")) <= (var.append_random_suffix ? (90 - 1 - var.random_suffix_length) : 90)
)
)
error_message = "managed_resource_group_name must be 1-90 chars (or null to auto-generate) and leave room for '-<suffix>' when append_random_suffix is true."
}
}

variable "append_random_suffix" {
description = "Whether to append a random suffix to the workspace name (and managed RG name, if provided) to avoid collisions."
type = bool
default = true
}

variable "random_suffix_length" {
description = "Length of the random suffix appended when append_random_suffix is true."
type = number
default = 6

validation {
condition = var.random_suffix_length >= 4 && var.random_suffix_length <= 16
error_message = "random_suffix_length must be between 4 and 16."
}
}

variable "tags" {
description = "A map of tags to assign to the resources."
type = map(string)
default = {}
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Costa Rica
[![GitHub](https://img.shields.io/badge/--181717?logo=github&logoColor=ffffff)](https://github.com/)
[brown9804](https://github.com/brown9804)

Last updated: 2026-02-11
Last updated: 2026-02-12

----------

Expand Down Expand Up @@ -106,6 +106,7 @@ Last updated: 2026-02-11

- [Analytics and Big Data](./5_analytics-bigdata)
- [Azure Data Factory](./5_analytics-bigdata/data-factory)
- [Azure Databricks (Workspace)](./5_analytics-bigdata/databricks)
- [Azure Synapse Analytics (Workspace)](./5_analytics-bigdata/synapse-analytics)

</details>
Expand Down