Créez des clusters, des notebooks et des jobs avec Terraform
Cet article montre comment utiliser le fournisseur Databricks Terraform pour créer un cluster, un Notebook et un Job dans un Workspace Databricks existant.
Vous pouvez également adapter les configurations Terraform de cet article pour créer des clusters, des Notebooks et des Jobs personnalisés dans vos Workspace.
Étape 1 : créer et configurer le projet Terraform
-
Créez un projet Terraform en suivant les instructions de la section Exigences de l'article de présentation du fournisseur Databricks Terraform.
-
Pour créer un cluster, créez un fichier nommé
cluster.tf, puis ajoutez le contenu suivant au fichier. Ce contenu crée un cluster avec la plus petite quantité de ressources autorisée. Ce cluster utilise la dernière version de Databricks Runtime (support à long terme, LTS).Pour un cluster qui fonctionne avec Unity Catalog :
variable "cluster_name" {}
variable "cluster_autotermination_minutes" {}
variable "cluster_num_workers" {}
variable "cluster_data_security_mode" {}
# Create the cluster with the "smallest" amount
# of resources allowed.
data "databricks_node_type" "smallest" {
local_disk = true
}
# Use the latest Databricks Runtime
# Long Term Support (LTS) version.
data "databricks_spark_version" "latest_lts" {
long_term_support = true
}
resource "databricks_cluster" "this" {
cluster_name = var.cluster_name
node_type_id = data.databricks_node_type.smallest.id
spark_version = data.databricks_spark_version.latest_lts.id
autotermination_minutes = var.cluster_autotermination_minutes
num_workers = var.cluster_num_workers
data_security_mode = var.cluster_data_security_mode
}
output "cluster_url" {
value = databricks_cluster.this.url
}
Pour un cluster polyvalent :
variable "cluster_name" {
description = "A name for the cluster."
type = string
default = "My Cluster"
}
variable "cluster_autotermination_minutes" {
description = "How many minutes before automatically terminating due to inactivity."
type = number
default = 60
}
variable "cluster_num_workers" {
description = "The number of workers."
type = number
default = 1
}
# Create the cluster with the "smallest" amount
# of resources allowed.
data "databricks_node_type" "smallest" {
local_disk = true
}
# Use the latest Databricks Runtime
# Long Term Support (LTS) version.
data "databricks_spark_version" "latest_lts" {
long_term_support = true
}
resource "databricks_cluster" "this" {
cluster_name = var.cluster_name
node_type_id = data.databricks_node_type.smallest.id
spark_version = data.databricks_spark_version.latest_lts.id
autotermination_minutes = var.cluster_autotermination_minutes
num_workers = var.cluster_num_workers
}
output "cluster_url" {
value = databricks_cluster.this.url
}
-
Pour créer un cluster, créez un autre fichier nommé
cluster.auto.tfvarset ajoutez le contenu suivant au fichier. Ce fichier contient les valeurs des variables pour personnaliser le cluster. Remplacez les valeurs des espaces réservés par vos propres valeurs.Pour un cluster qui fonctionne avec Unity Catalog :
cluster_name = "My Cluster"
cluster_autotermination_minutes = 60
cluster_num_workers = 1
cluster_data_security_mode = "SINGLE_USER"
Pour un cluster polyvalent :
cluster_name = "My Cluster"
cluster_autotermination_minutes = 60
cluster_num_workers = 1
- Pour créer un Notebook, créez un autre fichier nommé
notebook.tfet ajoutez le contenu suivant au fichier :
variable "notebook_subdirectory" {
description = "A name for the subdirectory to store the notebook."
type = string
default = "Terraform"
}
variable "notebook_filename" {
description = "The notebook's filename."
type = string
}
variable "notebook_language" {
description = "The language of the notebook."
type = string
}
resource "databricks_notebook" "this" {
path = "${data.databricks_current_user.me.home}/${var.notebook_subdirectory}/${var.notebook_filename}"
language = var.notebook_language
source = "./${var.notebook_filename}"
}
output "notebook_url" {
value = databricks_notebook.this.url
}
-
Si vous créez un cluster, enregistrez le code de Notebook suivant dans un fichier dans le même répertoire que le fichier
notebook.tf:Pour le Notebook Python, utilisez le code suivant :
# Databricks notebook source
# Import functions
from pyspark.sql.functions import col, current_timestamp
# Define variables used in code below
file_path = "/databricks-datasets/structured-streaming/events"
username = spark.sql("SELECT regexp_replace(session_user(), '[^a-zA-Z0-9]', '_')").first()[0]
table_name = f"{username}_etl_quickstart"
checkpoint_path = f"/tmp/{username}/_checkpoint/etl_quickstart"
# Clear out data from previous demo execution
spark.sql(f"DROP TABLE IF EXISTS {table_name}")
dbutils.fs.rm(checkpoint_path, True)
# Configure Auto Loader to ingest JSON data to a Delta table
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.schemaLocation", checkpoint_path)
.load(file_path)
.select("*", col("_metadata.file_path").alias("source_file"), current_timestamp().alias("processing_time"))
.writeStream
.option("checkpointLocation", checkpoint_path)
.trigger(availableNow=True)
.toTable(table_name))
# COMMAND ----------
df = spark.read.table(table_name)
# COMMAND ----------
display(df)
Pour le notebook SQL, utilisez le code suivant :
-- Databricks notebook source
-- MAGIC %python
-- MAGIC diamonds = (spark.read
-- MAGIC .format("csv")
-- MAGIC .option("header", "true")
-- MAGIC .option("inferSchema", "true")
-- MAGIC .load("/databricks-datasets/Rdatasets/data-001/csv/ggplot2/diamonds.csv")
-- MAGIC )
-- MAGIC
-- MAGIC diamonds.write.format("delta").save("/mnt/delta/diamonds")
-- COMMAND ----------
DROP TABLE IF EXISTS diamonds;
CREATE TABLE diamonds USING DELTA LOCATION '/mnt/delta/diamonds/'
-- COMMAND ----------
SELECT color, avg(price) AS price FROM diamonds GROUP BY color ORDER BY COLOR
Pour le Notebook Python, utilisez le code suivant :
# Databricks notebook source
external_location = "<your_external_location>"
catalog = "<your_catalog>"
dbutils.fs.put(f"{external_location}/foobar.txt", "Hello world!", True)
display(dbutils.fs.head(f"{external_location}/foobar.txt"))
dbutils.fs.rm(f"{external_location}/foobar.txt")
display(spark.sql(f"SHOW SCHEMAS IN {catalog}"))
# COMMAND ----------
from pyspark.sql.functions import col
# Set parameters for isolation in workspace and reset demo
username = spark.sql("SELECT regexp_replace(session_user(), '[^a-zA-Z0-9]', '_')").first()[0]
database = f"{catalog}.e2e_lakehouse_{username}_db"
source = f"{external_location}/e2e-lakehouse-source"
table = f"{database}.target_table"
checkpoint_path = f"{external_location}/_checkpoint/e2e-lakehouse-demo"
spark.sql(f"SET c.username='{username}'")
spark.sql(f"SET c.database={database}")
spark.sql(f"SET c.source='{source}'")
spark.sql("DROP DATABASE IF EXISTS ${c.database} CASCADE")
spark.sql("CREATE DATABASE ${c.database}")
spark.sql("USE ${c.database}")
# Clear out data from previous demo execution
dbutils.fs.rm(source, True)
dbutils.fs.rm(checkpoint_path, True)
# Define a class to load batches of data to source
class LoadData:
def __init__(self, source):
self.source = source
def get_date(self):
try:
df = spark.read.format("json").load(source)
except:
return "2016-01-01"
batch_date = df.selectExpr("max(distinct(date(tpep_pickup_datetime))) + 1 day").first()[0]
if batch_date.month == 3:
raise Exception("Source data exhausted")
return batch_date
def get_batch(self, batch_date):
return (
spark.table("samples.nyctaxi.trips")
.filter(col("tpep_pickup_datetime").cast("date") == batch_date)
)
def write_batch(self, batch):
batch.write.format("json").mode("append").save(self.source)
def land_batch(self):
batch_date = self.get_date()
batch = self.get_batch(batch_date)
self.write_batch(batch)
RawData = LoadData(source)
# COMMAND ----------
RawData.land_batch()
# COMMAND ----------
# Import functions
from pyspark.sql.functions import col, current_timestamp
# Configure Auto Loader to ingest JSON data to a Delta table
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.schemaLocation", checkpoint_path)
.load(source)
.select("*", col("_metadata.file_path").alias("source_file"), current_timestamp().alias("processing_time"))
.writeStream
.option("checkpointLocation", checkpoint_path)
.trigger(availableNow=True)
.option("mergeSchema", "true")
.toTable(table))
# COMMAND ----------
df = spark.read.table(table)
# COMMAND ----------
display(df)
-
Si vous créez un notebook, créez un autre fichier nommé
notebook.auto.tfvars, et ajoutez le contenu suivant au fichier. Ce fichier contient les valeurs de variables pour personnaliser la configuration du Notebook.Pour le Notebook Python :
notebook_subdirectory = "Terraform"
notebook_filename = "notebook-getting-started-etl-quick-start.py"
notebook_language = "PYTHON"
Pour le notebook SQL :
notebook_subdirectory = "Terraform"
notebook_filename = "notebook-getting-started-quickstart.sql"
notebook_language = "SQL"
Pour le Notebook Python :
notebook_subdirectory = "Terraform"
notebook_filename = "notebook-getting-started-lakehouse-e2e.py"
notebook_language = "PYTHON"
- Pour créer le job, créez un autre fichier nommé
job.tf, et ajoutez le contenu suivant au fichier. Ce contenu crée un job pour exécuter le Notebook.
variable "job_name" {
description = "A name for the job."
type = string
default = "My Job"
}
variable "task_key" {
description = "A name for the task."
type = string
default = "my_task"
}
resource "databricks_job" "this" {
name = var.job_name
task {
task_key = var.task_key
existing_cluster_id = databricks_cluster.this.cluster_id
notebook_task {
notebook_path = databricks_notebook.this.path
}
}
email_notifications {
on_success = [ data.databricks_current_user.me.user_name ]
on_failure = [ data.databricks_current_user.me.user_name ]
}
}
output "job_url" {
value = databricks_job.this.url
}
- Si vous créez un Job, créez un autre fichier nommé
job.auto.tfvarset ajoutez le contenu suivant au fichier. Ce fichier contient une valeur de variable pour personnaliser la configuration du Job.
job_name = "My Job"
task_key = "my_task"
Étape 2 : exécuter les configurations
À cette étape, vous exécutez les configurations Terraform pour déployer le cluster, le Notebook et le Job dans votre Workspace Databricks.
-
Vérifiez la validité de vos configurations Terraform en exécutant la commande
terraform validate. Si des erreurs sont signalées, corrigez-les et relancez la commande.Bashterraform validate -
Vérifiez ce que Terraform fera dans votre Workspace, avant que Terraform ne le fasse réellement, en exécutant la commande
terraform plan.Bashterraform plan -
Déployez le cluster, le notebook et le Job dans votre Workspace en exécutant la commande
terraform apply. Lorsque vous êtes invité à déployer, saisissezyeset appuyez sur Entrée .Bashterraform applyTerraform déploie les ressources spécifiées dans votre projet. Le déploiement de ces Ressources (notamment d'un cluster) peut prendre plusieurs minutes.
Étape 3 : explorez les résultats
-
Si vous avez créé un cluster, dans la sortie de la commande
terraform apply, copiez le Link situé à côté decluster_urlet collez-le dans la barre d'adresse de votre navigateur web. -
Si vous avez créé un notebook, dans la sortie de la commande
terraform apply, copiez le Link à côté denotebook_url, et collez-le dans la barre d'adresse de votre navigateur web.
Avant d'utiliser le notebook, vous devrez peut-être personnaliser son contenu. Consultez la documentation associée sur la façon de personnaliser le Notebook.
- Si vous avez créé un job, dans la sortie de la commande
terraform apply, copiez le link à côté dejob_urlet collez-le dans la barre d'adresse de votre navigateur web.
Avant d'exécuter le Notebook, vous pourriez avoir besoin de personnaliser son contenu. Veuillez consulter les Link au début de cet article pour la documentation associée sur la personnalisation du Notebook.
-
Si vous avez créé un Job, exécutez-le comme suit :
- Cliquez sur Exécuter maintenant sur la page du Job.
- Une fois le Job terminé, pour afficher les résultats de l'exécution du Job, dans la liste **Exécutions terminées (60 derniers jours)** de la page du Job, cliquez sur l'entrée de temps la plus récente dans la colonne **Heure de start**. Le volet **Sortie** affiche le résultat de l'exécution du code du Notebook.
Étape 4 : Nettoyer
Dans cette étape, vous supprimez les ressources précédentes de votre Workspace.
-
Vérifiez ce que Terraform fera dans votre Workspace, avant que Terraform ne le fasse réellement, en exécutant la commande
terraform plan.Bashterraform plan -
Supprimez le cluster, le Notebook et le Job de votre Workspace en exécutant la commande
terraform destroy. Lorsque vous êtes invité à supprimer, tapezyeset appuyez sur Entrée .Bashterraform destroyTerraform supprime les ressources qui sont spécifiées dans votre projet.