Typisk installation av Lakebase-projekt med Terraform

Important

Terraform-stöd för Lakebase är i beta.

Den här sidan visar en komplett Terraform-konfiguration för ett produktionsklart Lakebase-projekt med de mest använda funktionerna:

  • Skyddad produktionsgren
  • Slutpunkt för läsning och skrivning med hög tillgänglighet (HA) och läsbara sekundära repliker
  • Tjänstens huvudobjekt med DATABRICKS_SUPERUSER databasbehörigheter
  • Appägd Postgres-databas
  • Postgres-databas registrerad i Unity Catalog för Lakehouse Federation-förfrågningar i Databricks SQL och notebookfiler
  • Synkroniserad tabelluppspelning kontinuerligt från Unity Catalog
  • Databricks-appen är ansluten till Lakebase-projektet

En stegvis introduktion till Terraform med Lakebase finns i Komma igång med Terraform för Lakebase.

Förutsättningar

Innan du börjar måste du ha följande:

Fullständig konfiguration

När du skapar ett projekt skapar Azure Databricks automatiskt en production gren, en primary skrivskyddad slutpunkt, en postgres-ägarroll som är kopplad till din identitet och en databricks_postgres databas. Om du vill konfigurera dessa implicit skapade resurser deklarerar du dem i Terraform med replace_existing = true. Mer information finns i databricks_postgres_branch, databricks_postgres_endpoint, databricks_postgres_roleoch databricks_postgres_database.

Varning

Den här konfigurationen anger is_protected = true för grenen production och innehåller variabeln unprotect_for_destroy, som används i grenspecifikationen. Terraform kan inte ta bort ett projekt som innehåller skyddade grenar och grenen production kan inte tas bort direkt eftersom dess livscykel styrs av projektet. Om du vill ta bort resurser på ett rent sätt använder du en tvåstegsdestruering:

# Step 1: unprotect the branch
terraform apply -var="unprotect_for_destroy=true"

# Step 2: destroy all resources
terraform destroy -var="unprotect_for_destroy=true"

När terraform destroy har körts, mjukraderas projektet och behålls i 7 dagar innan det tas bort permanent. Om du vill ta bort den permanent direkt anger du purge_on_delete = true på resursen databricks_postgres_project innan du kör destroy.

variable "admin_sp_app_id" {
  description = "Application ID of the service principal to grant admin access"
  type        = string
}

variable "unprotect_for_destroy" {
  description = "Set to true before destroy to unprotect the production branch"
  type        = bool
  default     = false
}

# Project — top-level container for branches, endpoints, databases, and roles.
resource "databricks_postgres_project" "this" {
  project_id = "my-lakebase-project"
  # purge_on_delete = true  # Uncomment to permanently delete on destroy (default: soft delete, 7-day retention).
  spec = {
    pg_version   = 17
    display_name = "My Lakebase Project"
    default_endpoint_settings = {
      autoscaling_limit_min_cu = 0.5
      autoscaling_limit_max_cu = 4.0
      suspend_timeout_duration = "300s"
    }
  }
}

# Configure the implicitly created production branch as protected.
resource "databricks_postgres_branch" "production" {
  branch_id = "production"
  parent    = databricks_postgres_project.this.name
  spec = {
    no_expiry    = true
    is_protected = var.unprotect_for_destroy ? false : true
  }
  replace_existing = true
}

# Configure the implicitly created primary endpoint with HA.
# HA requires no_suspension = true. group.min = 2 adds a standby for automatic failover.
resource "databricks_postgres_endpoint" "primary" {
  endpoint_id = "primary"
  parent      = databricks_postgres_branch.production.name
  spec = {
    endpoint_type            = "ENDPOINT_TYPE_READ_WRITE"
    autoscaling_limit_min_cu = 0.5
    autoscaling_limit_max_cu = 4.0
    no_suspension            = true
    group = {
      min                         = 2
      max                         = 2
      enable_readable_secondaries = true
    }
  }
  replace_existing = true
}

# Grant workspace-level CAN_MANAGE on the project to the service principal.
# Use status.project_id (bare ID) not .name (full resource path) — the permissions
# API rejects the full path with a "resource type not found" error.
resource "databricks_permissions" "project" {
  database_project_name = databricks_postgres_project.this.status.project_id
  access_control {
    service_principal_name = var.admin_sp_app_id
    permission_level       = "CAN_MANAGE"
  }
}

# Create a Postgres role backed by the service principal with full database privileges.
# depends_on serializes creation — Lakebase processes one branch operation at a time.
resource "databricks_postgres_role" "admin_sp" {
  role_id = "admin-sp"
  parent  = databricks_postgres_branch.production.name
  spec = {
    identity_type    = "SERVICE_PRINCIPAL"
    postgres_role    = var.admin_sp_app_id
    auth_method      = "LAKEBASE_OAUTH_V1"
    membership_roles = ["DATABRICKS_SUPERUSER"]
    attributes = {
      createdb   = true
      createrole = true
      bypassrls  = true
    }
  }
  depends_on = [databricks_postgres_endpoint.primary]
}

# Create a Postgres database owned by the admin SP role.
resource "databricks_postgres_database" "app" {
  database_id = "app"
  parent      = databricks_postgres_branch.production.name
  spec = {
    postgres_database = "app"
    role              = databricks_postgres_role.admin_sp.name
  }
}

# Register the Postgres database in Unity Catalog. This makes the database queryable
# from Databricks SQL and notebooks through Lakehouse Federation, and serves as the
# parent namespace for synced tables that live inside the Lakebase Catalog.
# create_database_if_missing is set explicitly because the database is managed by
# the databricks_postgres_database resource above.
resource "databricks_postgres_catalog" "app_catalog" {
  catalog_id = "app_catalog"
  spec = {
    postgres_database          = databricks_postgres_database.app.status.postgres_database
    branch                     = databricks_postgres_branch.production.name
    create_database_if_missing = false
  }
}

# Sync a Unity Catalog Delta table into the Lakebase database continuously.
# Prefixing synced_table_id with the Lakebase Catalog name places the synced table
# inside the catalog so it's discoverable alongside the rest of the catalog's contents.
# postgres_database references the catalog's status, which implicitly orders this
# resource after the catalog without an explicit depends_on.
resource "databricks_postgres_synced_table" "orders" {
  synced_table_id = "app_catalog.default.orders_synced"
  spec = {
    branch                             = databricks_postgres_branch.production.name
    postgres_database                  = databricks_postgres_catalog.app_catalog.status.postgres_database
    source_table_full_name             = "my_catalog.default.orders"
    primary_key_columns                = ["order_id"]
    scheduling_policy                  = "CONTINUOUS"
    create_database_objects_if_missing = true
    new_pipeline_spec = {
      storage_catalog = "my_catalog"
      storage_schema  = "default"
    }
  }
}

# Databricks App connected to the Lakebase project.
# database must be the full resource name (databricks_postgres_database.app.name),
# not the Postgres database name. permission must be "CAN_CONNECT_AND_CREATE".
resource "databricks_app" "this" {
  name        = "my-lakebase-app"
  description = "App backed by Lakebase autoscaling project"
  depends_on  = [databricks_postgres_database.app]
  resources = [{
    name = "lakebase-db"
    postgres = {
      branch     = databricks_postgres_branch.production.name
      database   = databricks_postgres_database.app.name
      permission = "CAN_CONNECT_AND_CREATE"
    }
  }]
}

Note

Den här konfigurationen skapar en separat roll (admin_sp) och databas (app) i stället för att hantera den implicita ägarrollen och databricks_postgres databasen. För att i stället hantera dessa underförstådda resurser med Terraform deklarerar du dem med replace_existing = true och använder deras befintliga ID:n. Databas-ID:t är alltid databricks-postgres. Roll-ID:t härleds från den identitet som skapade grenen: delen av e-postmeddelandet före @ (nedsänkta, icke-alfanumeriska tecken ersatta med bindestreck) för en användare eller sp-<application-id> för ett huvudnamn för tjänsten. Om du är osäker på det exakta värdet, läs det från Lakebase-appen eller Postgres API istället för att härleda det för hand.

spec.membership_roles skriver över rollens medlemskap vid varje tillämpning i stället för att sammanfoga dem. Behåll DATABRICKS_SUPERUSER i listan; om du utelämnar den tas alla rollens medlemskap bort.

resource "databricks_postgres_role" "owner" {
  role_id = "jane-doe" # normalized login of the creating identity
  parent  = databricks_postgres_branch.production.name
  spec = {
    postgres_role    = "jane.doe@databricks.com" # the raw login
    membership_roles = ["DATABRICKS_SUPERUSER"]
    attributes = {
      createdb   = true
      createrole = true
      bypassrls  = true
    }
  }
  replace_existing = true
}

resource "databricks_postgres_database" "databricks_postgres" {
  database_id = "databricks-postgres"
  parent      = databricks_postgres_branch.production.name
  spec = {
    postgres_database = "databricks_postgres"
    # spec.role is omitted, so the database keeps its existing owner.
  }
  replace_existing = true
}

Ytterligare resurser