Skip to content

Commit

Permalink
Azure Databricks Access Connector module (#243)
Browse files Browse the repository at this point in the history
* adb-access-connector module

* update README

* adjust precondition

* terraform-docs: automated action

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
jdocampo and github-actions[bot] authored Jul 17, 2023
1 parent 57b0f32 commit 1acc979
Show file tree
Hide file tree
Showing 12 changed files with 327 additions and 1 deletion.
98 changes: 98 additions & 0 deletions .github/workflows/databricks-access-connector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Module:databricks-access-connector
on:
workflow_dispatch:
pull_request:
branches:
- main
paths:
- '.github/workflows/databricks-access-connector.yml'
- 'terraform/databricks/access-connector/**'
# - '.github/actions/**'

env:
terraform_workingdir: "terraform/databricks/access-connector"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
terraform-lint:
name: Run Terraform lint
runs-on: ubuntu-latest
defaults:
run:
working-directory: "${{ env.terraform_workingdir }}"

steps:
- uses: actions/checkout@v3
- uses: hashicorp/setup-terraform@v2

- name: Terraform fmt
id: fmt
run: terraform fmt -check
continue-on-error: false

terraform-sec:
name: Run Terraform tfsec
needs:
- terraform-lint
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@main

- name: Run tfsec with reviewdog output on the PR
uses: ./.github/actions/run-terraform-sec

terratest:
name: Run Terratest
needs:
- terraform-sec
runs-on: [self-hosted, 1ES.Pool=azure-data-labs-modules]
environment:
name: acctests

defaults:
run:
working-directory: "${{ env.terraform_workingdir }}/test"

steps:
- name: Check out code
uses: actions/checkout@v3


- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18.2

- name: Setup Dependencies
run: |
az login --identity > /dev/null
export ARM_USE_MSI=true
export ARM_SUBSCRIPTION_ID=$(az login --identity | jq -r '.[0] | .id')
export ARM_TENANT_ID=$(az login --identity | jq -r '.[0] | .tenantId')
go mod init test && go mod tidy
env:
GOPATH: "/home/cloudtest/work/azure-labs-modules/azure-labs-modules/${{ env.terraform_workingdir }}"

- name: Unit-test
run: |
az login --identity > /dev/null
export ARM_USE_MSI=true
export ARM_SUBSCRIPTION_ID=$(az login --identity | jq -r '.[0] | .id')
export ARM_TENANT_ID=$(az login --identity | jq -r '.[0] | .tenantId')
go test -v -timeout 45m
env:
GOPATH: "/home/cloudtest/work/azure-labs-modules/azure-labs-modules/${{ env.terraform_workingdir }}"

terraform-docs:
name: Run Terraform Docs
needs:
- terratest
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v3

- name: Render terraform docs and push changes back to PR
uses: ./.github/actions/run-terraform-docs
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ Looking for **built-in templates**? Check out [Azure Data Labs templates](https:
| [Data Factory / Self-Hosted Integration Runtime](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/data-factory/self-hosted-integration-runtime) | [![Module:self-hosted-integration-runtime](https://github.com/Azure/azure-data-labs-modules/actions/workflows/self-hosted-integration-runtime.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/self-hosted-integration-runtime.yml) |
| [Data Share / Data Share](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/data-share/data-share) | [![Module:data-share](https://github.com/Azure/azure-data-labs-modules/actions/workflows/data-share.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/data-share.yml) |
| [Data Share / Data Share Account](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/data-share/data-share-account) | [![Module:data-share-account](https://github.com/Azure/azure-data-labs-modules/actions/workflows/data-share-account.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/data-share-account.yml) |
| [Databricks / Workspace](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/databricks) | [![Module:databricks](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks.yml) |
| [Databricks / Workspace](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/databricks/databricks-workspace) | [![Module:databricks](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks.yml) |
| [Databricks / Access Connector](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/databricks/access-connector) | [![Module:databricks-access-connector](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks-access-connector.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/databricks-access-connector.yml) |
| [Event Grid / Domain](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/event-grid/event-grid-domain) | [![Module:event-grid-domain](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-grid-domain.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-grid-domain.yml)
| [Event Grid / Topic](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/event-grid/event-grid-topic) | [![Module:event-grid-topic](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-grid-topic.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-grid-topic.yml)
| [Event Hubs / Event Hubs](https://github.com/Azure/azure-data-labs-modules/tree/main/terraform/event-hubs/event-hubs) | [![Module:event-hubs-namespace](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-hubs.yml/badge.svg)](https://github.com/Azure/azure-data-labs-modules/actions/workflows/event-hubs.yml)
Expand Down
25 changes: 25 additions & 0 deletions terraform/databricks/access-connector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!-- BEGIN_TF_DOCS -->
## Resources

| Name | Type |
|------|------|
| [azurerm_databricks_access_connector.adl_adb_access_connector](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/databricks_access_connector) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_basename"></a> [basename](#input\_basename) | Basename of the module. | `string` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group name. | `string` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | Location of the resource group. | `string` | n/a | yes |
| <a name="input_identity_ids"></a> [identity\_ids](#input\_identity\_ids) | Specifies the IDs of the User Assigned Managed Identities to be assigned to the Databricks Access Connector. Only one User Assigned Managed Identity ID is supported per Databricks Access Connector resource. | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags which should be assigned to the deployed resource. | `map(string)` | `{}` | no |
| <a name="input_module_enabled"></a> [module\_enabled](#input\_module\_enabled) | Variable to enable or disable the module. | `bool` | `true` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | The ID of the Databricks Access Connector in the Azure management plane. |
| <a name="output_identity"></a> [identity](#output\_identity) | A list of identity blocks containing the system-assigned managed identities. |
<!-- END_TF_DOCS -->
23 changes: 23 additions & 0 deletions terraform/databricks/access-connector/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/databricks_access_connector

resource "azurerm_databricks_access_connector" "adl_adb_access_connector" {
name = "adb-ac-${var.basename}"
resource_group_name = var.resource_group_name
location = var.location

identity {
type = length(var.identity_ids) == 0 ? "SystemAssigned" : "UserAssigned"
identity_ids = length(var.identity_ids) == 0 ? [] : var.identity_ids
}

tags = var.tags

count = var.module_enabled ? 1 : 0

lifecycle {
precondition {
condition = length(var.identity_ids) < 2
error_message = "Only one User Assigned Managed Identity ID is supported per Databricks Access Connector resource."
}
}
}
15 changes: 15 additions & 0 deletions terraform/databricks/access-connector/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "id" {
value = (
length(azurerm_databricks_access_connector.adl_adb_access_connector) > 0 ?
azurerm_databricks_access_connector.adl_adb_access_connector[0].id : null
)
description = "The ID of the Databricks Access Connector in the Azure management plane."
}

output "identity" {
value = (
length(azurerm_databricks_access_connector.adl_adb_access_connector) > 0 ?
azurerm_databricks_access_connector.adl_adb_access_connector[0].identity : null
)
description = "A list of identity blocks containing the system-assigned managed identities."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module "access_connector_system_identity" {
source = "../"
basename = random_string.postfix.result
resource_group_name = module.local_rg.name
location = var.location
tags = {}
}

module "access_connector_user_identity" {
source = "../"
basename = random_string.postfix.result
resource_group_name = module.local_rg.name
location = var.location
identity_ids = [azurerm_user_assigned_identity.example.id]
tags = {}
}

resource "azurerm_user_assigned_identity" "example" {
location = var.location
name = "uami-${random_string.postfix.result}"
resource_group_name = module.local_rg.name
tags = {}
}

module "local_rg" {
source = "../../../resource-group"
basename = random_string.postfix.result
location = var.location
tags = local.tags
}
8 changes: 8 additions & 0 deletions terraform/databricks/access-connector/test/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
locals {
tags = {
Project = "Azure/azure-data-labs-modules"
Module = "databricks-workspace"
Toolkit = "Terraform"
}

}
15 changes: 15 additions & 0 deletions terraform/databricks/access-connector/test/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "ua_id" {
value = module.access_connector_system_identity.id
}

output "ua_identity" {
value = module.access_connector_system_identity.identity
}

output "sa_id" {
value = module.access_connector_user_identity.id
}

output "sa_identity" {
value = module.access_connector_user_identity.identity
}
23 changes: 23 additions & 0 deletions terraform/databricks/access-connector/test/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
terraform {
backend "azurerm" {
resource_group_name = "rg-adl-terraform-state"
storage_account_name = "stadlterraformstate"
container_name = "default"
key = "databricks.terraform.tfstate"
}

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "= 3.61.0"
}
databricks = {
source = "databricks/databricks"
version = "= 1.10.1"
}
}
}

provider "azurerm" {
features {}
}
38 changes: 38 additions & 0 deletions terraform/databricks/access-connector/test/unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package test

import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)

func TestModule(t *testing.T) {
t.Parallel()

terraformOptions := &terraform.Options{
TerraformDir: "./",
Lock: true,
LockTimeout: "1800s",
// VarFiles: []string{"terraform_unitest.tfvars"},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// Is used mainly for debugging, fail early if plan is not possible
terraform.InitAndPlan(t, terraformOptions)

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// Check if the outputs exist
assert := assert.New(t)
ua_id := terraform.Output(t, terraformOptions, "ua_id")
assert.NotNil(ua_id)
ua_identity := terraform.Output(t, terraformOptions, "ua_identity")
assert.NotNil(ua_identity)
sa_id := terraform.Output(t, terraformOptions, "sa_id")
assert.NotNil(sa_id)
sa_identity := terraform.Output(t, terraformOptions, "sa_identity")
assert.NotNil(sa_identity)
}
10 changes: 10 additions & 0 deletions terraform/databricks/access-connector/test/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "random_string" "postfix" {
length = 8
special = false
upper = false
}

variable "location" {
type = string
default = "North Europe"
}
40 changes: 40 additions & 0 deletions terraform/databricks/access-connector/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
variable "basename" {
type = string
description = "Basename of the module."
validation {
condition = can(regex("^[-\\w]{0,60}$", var.basename))
error_message = "The name must be between 0 and 60 characters, can contain only alphanumeric characters, underscores, and hyphens."
}
}

variable "resource_group_name" {
type = string
description = "Resource group name."
validation {
condition = can(regex("^[-\\w\\.\\(\\)]{1,90}$", var.resource_group_name)) && can(regex("[-\\w\\(\\)]+$", var.resource_group_name))
error_message = "Resource group names must be between 1 and 90 characters and can only include alphanumeric, underscore, parentheses, hyphen, period (except at end)."
}
}

variable "location" {
type = string
description = "Location of the resource group."
}

variable "identity_ids" {
type = list(string)
description = "Specifies the IDs of the User Assigned Managed Identities to be assigned to the Databricks Access Connector. Only one User Assigned Managed Identity ID is supported per Databricks Access Connector resource."
default = []
}

variable "tags" {
type = map(string)
default = {}
description = "A mapping of tags which should be assigned to the deployed resource."
}

variable "module_enabled" {
type = bool
description = "Variable to enable or disable the module."
default = true
}

0 comments on commit 1acc979

Please sign in to comment.