Pular para o conteúdo principal

Configuração típica de um projeto Lakebase com Terraform.

info

Beta

A partir de 15 de junho, o Lakebase está disponível em Beta no GCP. Consulte Disponibilidade regional para regiões compatíveis.

Esta página mostra uma configuração completa Terraform para um projeto Lakebase de escalonamento automático pronto para produção com o recurso mais comumente usado:

  • Ramo de produção protegido
  • endpoint de alta disponibilidade (HA) para leitura e gravação com secundários legíveis.
  • entidade de serviço com DATABRICKS_SUPERUSER privilégios de banco de dados
  • Banco de dados Postgres de propriedade do aplicativo
  • Banco de dados Postgres registrado no Unity Catalog para consultas do Lakehouse Federation do Databricks SQL e notebooks
  • Tabelas sincronizadas continuamente do Unity Catalog
  • Aplicativo Databricks conectado ao projeto Lakebase

Para uma introdução passo a passo ao Terraform com Lakebase, consulte Comece a usar Terraform para Lakebase.

Pré-requisitos

Antes de começar, deve ter o seguinte:

Configuração completa

Ao criar um projeto, o Databricks cria automaticamente uma ramificação production e um endpoint de leitura e gravação primary . Para configurar esses recursos criados implicitamente, declare-os no Terraform com replace_existing = true. Para mais detalhes, veja databricks_postgres_branch e databricks_postgres_endpoint.

atenção

Esta configuração define is_protected = true na branch production e inclui uma variável unprotect_for_destroy conectada à especificação da branch. O Terraform não pode excluir um projeto que contém branches protegidas, e a branch production não pode ser excluída diretamente porque seu ciclo de vida é controlado pelo projeto. Para remover recursos de forma limpa, use uma destruição em duas etapas:

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

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

Após a execução de terraform destroy, o projeto é excluído suavemente e retido por 7 dias antes da exclusão permanente. Para excluí-lo permanentemente imediatamente, defina purge_on_delete = true no recurso databricks_postgres_project antes de executar a exclusão.

Hcl
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"
}
}]
}

Recursos adicionais