Configuration typique de projet Lakebase avec Terraform
Cette page présente une configuration Terraform complète pour un projet Lakebase Autoscaling prêt pour la production avec les fonctionnalités les plus couramment utilisées :
- Branch de production protégée
- Endpoint en lecture-écriture à haute disponibilité (HA) avec des secondaires lisibles
- Service principal avec des privilèges de base de données
DATABRICKS_SUPERUSER - Base de données Postgres appartenant à l'application
- Base de données Postgres enregistrée dans Unity Catalog pour les query Lakehouse Federation à partir de Databricks SQL et de Notebook.
- Table synchronisée en streaming continu depuis Unity Catalog.
- Application Databricks connectée au projet Lakebase
Pour une introduction étape par étape à Terraform avec Lakebase, veuillez consulter Démarrer avec Terraform pour Lakebase.
Prérequis
Avant de commencer, vous devez disposer des éléments suivants :
- Terraform installé (version 1.0 ou supérieure). Consultez Installer Terraform.
- Un Service Principal configuré pour l’authentification OAuth de machine à machine (M2M) avec l’autorisation
CAN_MANAGEsur le projet Lakebase. Voir Autoriser l'accès du Service Principal à Databricks avec OAuth et Gérer les autorisations de projet. - Une table Delta Unity Catalog avec Change Data Feed (CDF) activé à utiliser comme source de synchronisation.
Configuration complète
Lorsque vous créez un projet, Databricks crée automatiquement une production branch, un primary endpoint en lecture-écriture, un rôle Postgres propriétaire lié à votre identité et une base de données databricks_postgres. Pour configurer ces ressources créées implicitement, déclarez-les dans Terraform avec replace_existing = true. Pour plus de détails, consultez databricks_postgres_branch, databricks_postgres_endpoint, databricks_postgres_role et databricks_postgres_database.
Cette configuration définit is_protected = true sur la Branch production et inclut une variable unprotect_for_destroy câblée dans la spécification de la Branch. Terraform ne peut pas supprimer un projet contenant des branches protégées, et la Branch production ne peut pas être supprimée directement, car son cycle de vie est contrôlé par le projet. Pour nettoyer les ressources proprement, utilisez une destruction en deux étapes :
# Step 1: unprotect the branch
terraform apply -var="unprotect_for_destroy=true"
# Step 2: destroy all resources
terraform destroy -var="unprotect_for_destroy=true"
Après l'exécution de terraform destroy, le projet est supprimé provisoirement et conservé pendant 7 jours avant sa suppression définitive. Pour le supprimer définitivement immédiatement, définissez purge_on_delete = true sur la Ressource databricks_postgres_project avant d'exécuter la destruction.
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"
}
}]
}
Cette configuration crée un rôle distinct (admin_sp) et une base de données (app) plutôt que de gérer le rôle de propriétaire implicite et la base de données databricks_postgres. Pour placer plutôt ces Ressources implicites sous la gestion Terraform, déclarez-les avec replace_existing = true en utilisant leurs ID existants. L'ID de la base de données est toujours databricks-postgres. L’ID du rôle est dérivé de l’identité qui a créé la Branch : la partie de l’e-mail avant @ (en minuscules, les caractères non alphanumériques remplacés par des tirets) pour un utilisateur, ou sp-<application-id> pour un Service Principal. Si vous n'êtes pas sûr de la valeur exacte, lisez-la depuis l'UI Lakebase ou l'API Postgres au lieu de la calculer manuellement.
spec.membership_roles Écrase les appartenances du rôle à chaque application plutôt que de les fusionner. Conservez DATABRICKS_SUPERUSER dans la liste ; le fait de l'omettre supprime toutes les appartenances du rôle.
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
}
Ressources supplémentaires
- La haute disponibilité couvre les modèles de haute disponibilité et leur utilisation en production.
- Synchronisez les tables traite des options de planification et de la gestion des pipelines.
- Gérer les autorisations du projet couvre les contrôles d'accès au niveau du workspace et de la base de données.
- Databricks Apps avec Lakebase montre comment connecter les applications aux projets de mise à l'échelle automatique.
- Le Terraform Registry fournit la référence complète des ressources.