Créer des clusters, des notebooks et des travaux avec Terraform

Cet article montre comment utiliser le fournisseur Databricks Terraform pour créer un cluster, un notebook et un travail dans un espace de travail Azure Databricks existant.

Cet article est un compagnon des articles pour bien démarrer d’Azure Databricks suivants :

Vous pouvez également adapter les configurations Terraform dans cet article pour créer des clusters personnalisés, des notebooks et des travaux dans vos espaces de travail.

Étape 1 : créer et configurer le projet Terraform

  1. Créez un projet Terraform en suivant les instructions de la section Spécifications de l’article de présentation du fournisseur Databricks Terraform.

  2. Pour créer un cluster, créez un fichier nommé cluster.tf et ajoutez-y le contenu suivant. Ce contenu crée un cluster avec la plus petite quantité de ressources autorisées. Ce cluster utilise la dernière version de Support à long terme (LTS) Databricks Runtime.

    Pour un cluster qui fonctionne avec le Catalogue Unity :

    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 à usage général :

    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
    }
    
  3. Pour créer un cluster, créez un autre fichier nommé cluster.auto.tfvars et ajoutez-y le contenu suivant. Ce fichier contient des valeurs variables pour personnaliser le cluster. Remplacez les valeurs d’espace réservé par vos propres valeurs.

    Pour un cluster qui fonctionne avec le Catalogue Unity :

    cluster_name                    = "My Cluster"
    cluster_autotermination_minutes = 60
    cluster_num_workers             = 1
    cluster_data_security_mode      = "SINGLE_USER"
    

    Pour un cluster à usage général :

    cluster_name                    = "My Cluster"
    cluster_autotermination_minutes = 60
    cluster_num_workers             = 1
    
  4. Pour créer un notebook, créez un autre fichier nommé notebook.tf et ajoutez-y le contenu suivant :

    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
    }
    
  5. Si vous créez un cluster, enregistrez le code de notebook suivant dans un fichier du même répertoire que le fichier notebook.tf :

    Pour le notebook Python pour Tutoriel : Exécuter un pipeline d’analyse lakehouse de bout en bout, un fichier nommé notebook-getting-started-lakehouse-e2e.py avec le contenu 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(current_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(file_path)
      .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_name)
    
    # COMMAND ----------
    
    display(df)
    

    Pour le notebook Python pour Démarrage rapide : Exécuter un travail Spark sur un espace de travail Azure Databricks à l’aide du portail Azure, un fichier nommé notebook-quickstart-create-databricks-workspace-portal.py avec le contenu suivant :

    # Databricks notebook source
    blob_account_name = "azureopendatastorage"
    blob_container_name = "citydatacontainer"
    blob_relative_path = "Safety/Release/city=Seattle"
    blob_sas_token = r""
    
    # COMMAND ----------
    
    wasbs_path = 'wasbs://%s@%s.blob.core.windows.net/%s' % (blob_container_name, blob_account_name,blob_relative_path)
    spark.conf.set('fs.azure.sas.%s.%s.blob.core.windows.net' % (blob_container_name, blob_account_name), blob_sas_token)
    print('Remote blob path: ' + wasbs_path)
    
    # COMMAND ----------
    
    df = spark.read.parquet(wasbs_path)
    print('Register the DataFrame as a SQL temporary view: source')
    df.createOrReplaceTempView('source')
    
    # COMMAND ----------
    
    print('Displaying top 10 rows: ')
    display(spark.sql('SELECT * FROM source LIMIT 10'))
    
  6. Si vous créez un notebook, créez un autre fichier nommé notebook.auto.tfvars et ajoutez-y le contenu suivant. Ce fichier contient des valeurs variables pour la personnalisation de la configuration du notebook.

    Pour le notebook Python pour le tutoriel : Exécuter un pipeline d’analyse lakehouse de bout en bout :

    notebook_subdirectory = "Terraform"
    notebook_filename     = "notebook-getting-started-lakehouse-e2e.py"
    notebook_language     = "PYTHON"
    

    Pour le notebook Python pour Démarrage rapide : Exécuter un travail Spark sur un espace de travail Azure Databricks à l’aide du portail Azure :

    notebook_subdirectory = "Terraform"
    notebook_filename     = "notebook-quickstart-create-databricks-workspace-portal.py"
    notebook_language     = "PYTHON"
    
  7. Si vous créez un notebook, dans votre espace de travail Azure Databricks, veillez à configurer les conditions requises pour que le notebook s’exécute correctement, en faisant référence aux instructions suivantes pour :

  8. Pour créer le travail, créez un autre fichier nommé job.tf et ajoutez-y le contenu suivant. Ce contenu crée un travail 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
    }
    
  9. Si vous créez un travail, créez un autre fichier nommé job.auto.tfvars et ajoutez-y le contenu suivant. Ce fichier contient une valeur variable pour personnaliser la configuration du travail.

    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 travail dans votre espace de travail Azure Databricks.

  1. Vérifiez si vos configurations Terraform sont valides en exécutant la commande terraform validate. Si des erreurs sont signalées, corrigez-les et réexécutez la commande.

    terraform validate
    
  2. Vérifiez ce que Terraform fera dans votre espace de travail, avant que Terraform ne le fasse réellement, en exécutant la commande terraform plan.

    terraform plan
    
  3. Déployez le cluster, le notebook et le travail dans votre espace de travail en exécutant la commande terraform apply. À l’invite de déploiement, tapez yes et appuyez sur Entrée.

    terraform apply
    

    Terraform déploie les ressources spécifiées dans votre projet. Le déploiement de ces ressources (en particulier un cluster) peut prendre plusieurs minutes.

Étape 3 : Explorer les résultats

  1. Si vous avez créé un cluster, dans la sortie de la commande terraform apply, copiez le lien en regard de cluster_url, puis collez-le dans la barre d’adresse de votre navigateur web.

  2. Si vous avez créé un notebook, dans la sortie de la commande terraform apply, copiez le lien en regard de notebook_url, puis collez-le dans la barre d’adresse de votre navigateur web.

    Notes

    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.

  3. Si vous avez créé un travail, dans la sortie de la commande terraform apply, copiez le lien en regard de job_url, puis collez-le dans la barre d’adresse de votre navigateur web.

    Notes

    Avant d’exécuter le notebook, vous devrez peut-être personnaliser son contenu. Consultez les liens au début de cet article pour obtenir de la documentation connexe sur la façon de personnaliser le notebook.

  4. Si vous avez créé un travail, exécutez le travail comme suit :

    1. Cliquez sur Exécuter maintenant sur la page du travail.
    2. Une fois le travail terminé, pour afficher les résultats de l’exécution du travail, dans la liste Exécutions terminées (au cours des 60 derniers jours) sur la page de travail, cliquez sur l’entrée de temps la plus récente dans la colonne Heure de début . Le volet Sortie affiche le résultat de l’exécution du code du notebook.

Étape 4 : nettoyer

À cette étape, vous supprimez les ressources précédentes de votre espace de travail.

  1. Vérifiez ce que Terraform fera dans votre espace de travail, avant que Terraform ne le fasse réellement, en exécutant la commande terraform plan.

    terraform plan
    
  2. Déployez le cluster, le notebook et le travail à partir de votre espace de travail en exécutant la commande terraform destroy. À l’invite de suppression, tapez yes et appuyez sur Entrée.

    terraform destroy
    

    Terraform supprime les ressources spécifiées dans votre projet.