Skip to content

Instantly share code, notes, and snippets.

@abij
Last active February 27, 2025 15:27
Show Gist options
  • Save abij/e2515f4275f46902dc26a46811e708e6 to your computer and use it in GitHub Desktop.
Save abij/e2515f4275f46902dc26a46811e708e6 to your computer and use it in GitHub Desktop.
All in one terraform example to manage Azure SCIM-app and Account-level groups.
terraform {
required_providers {
azuread = {
source = "hashicorp/azuread"
# Latest version selected
}
databricks = {
source = "databricks/databricks"
# Latest version selected
}
}
}
# === Providers ===============================================================
# Permissions required:
# - Add groups to SCIM-app: `Owner`
# - Lookup groups: `Group.Read.All` or `Directory.Read.All`
provider "azuread" {
}
# Permission required:
# - Add groups: `Account Admin`
provider "databricks" {
# Note: Account-level (not pointing to a Workspace)
host = "https://accounts.azuredatabricks.net"
account_id = "<here your Azure Databricks Account Id>" # found in Account-console (url)
auth_type = "azure-cli"
}
# === Variables ===============================================================
variable "input_group_names" {
type = list(string)
description = "EntraID group names to add in Databricks Account-level and SCIM-app for automatic user synchronization."
default = [
"group1",
"group2"
]
}
# === Data lookups ============================================================
# Check the groups that are available in Azure AD:
data "azuread_groups" "included" {
# This is more efficient then using "azuread_group" with a for_each.
# Only the object_id and display_name are returned, not all the members and many other properties.
display_names = var.input_group_names
}
# Lookup "Azure Databricks SCIM Provisioning Connector"
data "azuread_service_principal" "scim" {
client_id = "<here your SCIM app Client Id>"
}
# === Locals ==================================================================
locals {
# Make a mapping of the group name => object_id
included_groups = {
for i in range(length(data.azuread_groups.included.display_names)) :
data.azuread_groups.included.display_names[i] => data.azuread_groups.included.object_ids[i]
}
# Filter the app_role if there the display_name is "User" return its id
scim_app_user_role_id = [for r in data.azuread_service_principal.scim.app_roles: r.id if r.display_name == "User"][0]
}
# === Resources ===============================================================
# Create (empty) external groups in the Databrick Account-level.
resource "databricks_group" "scim" {
for_each = local.included_groups
display_name = each.key
external_id = each.value
force = true # don't fail when the group already exists.
}
# Create groups in SCIM-app for synchronization
resource "azuread_app_role_assignment" "scim_group" {
for_each = local.included_groups
app_role_id = local.scim_app_user_role_id
principal_object_id = each.value
resource_object_id = data.azuread_service_principal.scim.object_id
}
# Assign a non-user as owner of the SCIM-app:
#
# 0. Lookup the client-id of the SCIM-app
# 1. Lookup the object-id of the Service Principal to add as Owner.
# 2. Use Azure-CLI to assign the Owner
az rest --method post \
--url "https://graph.microsoft.com/v1.0/servicePrincipals(appId='SCIM_APP_CLIENT_ID')/owners/\$ref" \
--body '{"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/OBJECT-ID-OF-THE-SPN"}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment