Crie clusters, blocos de anotações e trabalhos com o Terraform

Este artigo mostra como usar o provedor Databricks Terraform para criar um cluster, um bloco de anotações e um trabalho em um espaço de trabalho existente do Azure Databricks.

Este artigo é complementar aos seguintes artigos de introdução do Azure Databricks:

Você também pode adaptar as configurações do Terraform neste artigo para criar clusters, blocos de anotações e trabalhos personalizados em seus espaços de trabalho.

Etapa 1: Criar e configurar o projeto Terraform

  1. Crie um projeto Terraform seguindo as instruções na seção Requisitos do artigo de visão geral do provedor Databricks Terraform.

  2. Para criar um cluster, crie um arquivo chamado cluster.tfe adicione o seguinte conteúdo ao arquivo. Esse conteúdo cria um cluster com a menor quantidade de recursos permitidos. Este cluster usa a versão mais recente do Databricks Runtime Long Term Support (LTS).

    Para um cluster que funciona com o 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
    }
    

    Para um cluster polivalente:

    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. Para criar um cluster, crie outro arquivo chamado cluster.auto.tfvarse adicione o seguinte conteúdo ao arquivo. Esse arquivo contém valores de variáveis para personalizar o cluster. Substitua os valores de espaço reservado por seus próprios valores.

    Para um cluster que funciona com o Unity Catalog:

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

    Para um cluster polivalente:

    cluster_name                    = "My Cluster"
    cluster_autotermination_minutes = 60
    cluster_num_workers             = 1
    
  4. Para criar um bloco de anotações, crie outro arquivo chamado notebook.tfe adicione o seguinte conteúdo ao arquivo:

    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. Se você estiver criando um cluster, salve o seguinte código de bloco de anotações em um arquivo no mesmo diretório que o notebook.tf arquivo:

    Para o bloco de anotações Python para Tutorial: Execute um pipeline de análise lakehouse de ponta a ponta, um arquivo nomeado notebook-getting-started-lakehouse-e2e.py com o seguinte conteúdo:

    # 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)
    

    Para o bloco de anotações Python para Guia de início rápido: executar um trabalho do Spark no espaço de trabalho do Azure Databricks usando o portal do Azure, um arquivo nomeado notebook-quickstart-create-databricks-workspace-portal.py com o seguinte conteúdo:

    # 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. Se estiver a criar um bloco de notas, crie outro ficheiro com o nome notebook.auto.tfvarse adicione o seguinte conteúdo ao ficheiro. Este arquivo contém valores variáveis para personalizar a configuração do notebook.

    Para o bloco de anotações Python para Tutorial: Execute um pipeline de análise lakehouse de ponta a ponta:

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

    Para o bloco de anotações Python para Guia de início rápido: execute um trabalho do Spark no espaço de trabalho do Azure Databricks usando o portal do Azure:

    notebook_subdirectory = "Terraform"
    notebook_filename     = "notebook-quickstart-create-databricks-workspace-portal.py"
    notebook_language     = "PYTHON"
    
  7. Se você estiver criando um bloco de anotações, em seu espaço de trabalho do Azure Databricks, certifique-se de configurar todos os requisitos para que o bloco de anotações seja executado com êxito, consultando as seguintes instruções para:

  8. Para criar o trabalho, crie outro arquivo chamado job.tfe adicione o seguinte conteúdo ao arquivo. Esse conteúdo cria um trabalho para executar o bloco de anotações.

    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. Se você estiver criando um trabalho, crie outro arquivo chamado job.auto.tfvarse adicione o seguinte conteúdo ao arquivo. Esse arquivo contém um valor variável para personalizar a configuração do trabalho.

    job_name = "My Job"
    task_key = "my_task"
    

Etapa 2: Executar as configurações

Nesta etapa, você executa as configurações do Terraform para implantar o cluster, o bloco de anotações e o trabalho em seu espaço de trabalho do Azure Databricks.

  1. Verifique se as configurações do Terraform são válidas executando o terraform validate comando. Se algum erro for relatado, corrija-o e execute o comando novamente.

    terraform validate
    
  2. Verifique o que o Terraform fará em seu espaço de trabalho, antes que o Terraform realmente o faça, executando o terraform plan comando.

    terraform plan
    
  3. Implante o cluster, o bloco de anotações e o trabalho em seu espaço de trabalho executando o terraform apply comando. Quando solicitado a implantar, digite yes e pressione Enter.

    terraform apply
    

    O Terraform implanta os recursos especificados em seu projeto. A implantação desses recursos (especialmente um cluster) pode levar vários minutos.

Passo 3: Explore os resultados

  1. Se você criou um cluster, na saída do comando, copie o link ao lado cluster_urlde e cole-o na barra de terraform apply endereço do navegador da Web.

  2. Se você criou um bloco de anotações, na saída do comando, copie o link ao lado de notebook_urle cole-o na barra de terraform apply endereço do navegador da Web.

    Nota

    Antes de usar o bloco de anotações, talvez seja necessário personalizar seu conteúdo. Consulte a documentação relacionada sobre como personalizar o bloco de anotações.

  3. Se você criou um trabalho, na saída do comando, copie o link ao lado job_urlde e cole-o na barra de terraform apply endereço do navegador da Web.

    Nota

    Antes de executar o bloco de anotações, talvez seja necessário personalizar seu conteúdo. Consulte os links no início deste artigo para obter documentação relacionada sobre como personalizar o bloco de anotações.

  4. Se você criou um trabalho, execute-o da seguinte maneira:

    1. Clique em Executar agora na página de trabalho.
    2. Após a conclusão da execução do trabalho, para exibir os resultados da execução do trabalho, na lista Execuções concluídas (últimos 60 dias) na página do trabalho, clique na entrada de hora mais recente na coluna Hora de início. O painel Saída mostra o resultado da execução do código do bloco de anotações.

Passo 4: Limpar

Nesta etapa, você exclui os recursos anteriores do seu espaço de trabalho.

  1. Verifique o que o Terraform fará em seu espaço de trabalho, antes que o Terraform realmente o faça, executando o terraform plan comando.

    terraform plan
    
  2. Exclua o cluster, o bloco de anotações e o trabalho do espaço de trabalho executando o terraform destroy comando. Quando solicitado a excluir, digite yes e pressione Enter.

    terraform destroy
    

    Terraform exclui os recursos que são especificados em seu projeto.