使用 Databricks Terraform 提供者建立叢集、筆記本和作業

本文說明如何使用Databricks Terraform 提供者,在現有的 Azure Databricks工作區中建立叢集筆記本作業

本文隨附于下列 Azure Databricks 使用者入門文章:

您也可以調整本文中的 Terraform 設定,以在工作區中建立自訂叢集、筆記本和作業。

規格需求

  • Azure Databricks 工作區。
  • 在您的本機開發電腦上,您必須具備:
    • Terraform CLI。 請參閱 在 Terraform 網站上下載 Terraform
    • 下列其中之一:
      • Databricks 命令列介面 (Databricks CLI) ,使用您的 Azure Databricks工作區實例 URL和 Azure Databricks 個人存取權杖進行設定,或藉由 databricks configure --token 設定環境變數,然後執行 databricks configure --aad-token 來 (DATABRICKS_AAD_TOKEN Azure AD) 權杖。 請參閱 設定 CLI設定驗證

        注意

        安全性最佳做法是,使用自動化工具、系統、腳本和應用程式進行驗證時,Databricks 建議您使用屬於服務主體的存取權杖,而不是工作區使用者。 如需詳細資訊,請參閱 管理服務主體

      • 透過 命令登入的 az login Azure CLI。 請參閱 如何安裝 Azure CLI 和使用 Azure CLI 登入

        注意

        安全性最佳做法是,使用自動化工具、系統、腳本和應用程式進行驗證時,Databricks 建議您使用 Azure Active Directory (Azure AD) 服務主體透過 命令登入 az login 。 請參閱 Azure Databricks 自動化的服務主體使用服務主體登入,以及 使用 Azure 服務主體進行驗證

      • 下列兩個環境變數:

        若要設定這些環境變數,請參閱作業系統的檔。

        注意

        安全性最佳做法是,使用自動化工具、系統、腳本和應用程式進行驗證時,Databricks 建議您使用屬於服務主體的存取權杖,而不是工作區使用者。 如需詳細資訊,請參閱 管理服務主體

步驟 1:設定 Terraform 專案

在此步驟中,您會設定 Terraform 專案,以定義要向工作區進行驗證的 Terraform 設定。 您也會定義 Terraform 部署到工作區的資源設定。

  1. 建立空的目錄,然後切換至它。 此目錄包含您的 Terraform 專案檔。 (每個個別的 Terraform 專案檔集都必須位於自己的父目錄中。) 若要這樣做,請在終端機或 PowerShell 中執行如下的命令:

    mkdir terraform_cluster_notebook_job && cd terraform_cluster_notebook_job
    
  2. 在此空白目錄中,建立名為 auth.tf 的檔案,並將下列內容新增至檔案。 此設定會初始化 Databricks Terraform 提供者,並使用您的工作區驗證 Terraform。

    若要使用 Databricks CLI 組態設定檔進行驗證,請新增下列內容:

    variable "databricks_connection_profile" {
      description = "The name of the Databricks connection profile to use."
      type        = string
    }
    
    # Initialize the Databricks Terraform provider.
    terraform {
      required_providers {
        databricks = {
          source = "databricks/databricks"
        }
      }
    }
    
    # Use Databricks CLI authentication.
    provider "databricks" {
      profile = var.databricks_connection_profile
    }
    
    # Retrieve information about the current user.
    data "databricks_current_user" "me" {}
    

    若要使用環境變數進行驗證,請改為新增下列內容:

    # Initialize the Databricks Terraform provider.
    terraform {
      required_providers {
        databricks = {
          source = "databricks/databricks"
        }
      }
    }
    
    # Use environment variables for authentication.
    provider "databricks" {}
    
    # Retrieve information about the current user.
    data "databricks_current_user" "me" {}
    

    若要使用 Azure CLI 進行驗證,請改為新增下列內容:

    variable "databricks_host" {
      description = "The Azure Databricks workspace URL."
      type        = string
    }
    
    # Initialize the Databricks Terraform provider.
    terraform {
      required_providers {
        databricks = {
          source = "databricks/databricks"
        }
      }
    }
    
    # Use Azure CLI authentication.
    provider "databricks" {
      host = var.databricks_host
    }
    
    # Retrieve information about the current user.
    data "databricks_current_user" "me" {}
    
  3. 建立名為 的另 auth.auto.tfvars 一個檔案,並將下列內容新增至 檔案。 此檔案包含用來向工作區驗證 Terraform 的變數值。 以您自己的值取代預留位置值。

    若要使用 Databricks CLI 組態設定檔進行驗證,請新增下列內容:

    databricks_connection_profile = "DEFAULT"
    

    若要使用 Azure CLI 進行驗證,請改為新增下列內容:

    databricks_host = "https://<workspace-instance-name>"
    

    若要使用環境變數進行驗證,您不需要 auth.auto.tfvars 檔案。

  4. 執行 terraform init 命令。 此命令會建立其他協助程式檔案並下載必要的 Terraform 模組,以初始化您的 Terraform 專案。

    terraform init
    
  5. 如果您要建立叢集,請建立名為 cluster.tf 的另一個檔案,並將下列內容新增至檔案。 此內容會建立允許最少資源的叢集。 此叢集使用最新的 Databricks Runtime 長期支援 (LTS) 版本。

    適用于 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
    }
    

    針對全用途叢集:

    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
    }
    
  6. 如果您要建立叢集,請建立名為 cluster.auto.tfvars 的另一個檔案,並將下列內容新增至檔案。 此檔案包含自訂叢集的變數值。 以您自己的值取代預留位置值。

    適用于 Unity 目錄的叢集:

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

    針對全用途叢集:

    cluster_name                    = "My Cluster"
    cluster_autotermination_minutes = 60
    cluster_num_workers             = 1
    
  7. 如果您要建立筆記本,請建立另一個名為 notebook.tf 的檔案,並將下列內容新增至檔案:

    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
    }
    
  8. 將下列筆記本程式碼儲存至與檔案位於相同目錄中的 notebook.tf 檔案:

    針對在 Databricks Lakehouse 中執行第一個端對端分析管線的Python 筆記本,其檔案名為 notebook-getting-started-lakehouse-e2e.py ,其中包含下列內容:

    # 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 input_file_name, 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("*", input_file_name().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)
    

    針對 Python Notebook for Quickstart:使用 Azure 入口網站 在 Azure Databricks 工作區上執行 Spark 作業,這是名為 notebook-quickstart-create-databricks-workspace-portal.py 的檔案,其中包含下列內容:

    # 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'))
    
  9. 如果您要建立筆記本,請建立另一個名為 notebook.auto.tfvars 的檔案,並將下列內容新增至檔案。 此檔案包含自訂筆記本組態的變數值。

    針對在 Databricks Lakehouse 中執行第一個端對端分析管線的Python 筆記本:

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

    如需快速入門的 Python 筆記本:使用 Azure 入口網站在 Azure Databricks 工作區上執行 Spark 作業

    notebook_subdirectory = "Terraform"
    notebook_filename     = "notebook-quickstart-create-databricks-workspace-portal.py"
    notebook_language     = "PYTHON"
    
  10. 如果您要在 Azure Databricks 工作區中建立筆記本,請務必參考下列指示,設定筆記本順利執行的任何需求:

  11. 如果您要建立作業,請建立名為 job.tf 的另一個檔案,並將下列內容新增至檔案。 此內容會建立作業來執行筆記本。

    variable "job_name" {
      description = "A name for the job."
      type        = string
      default     = "My Job"
    }
    
    resource "databricks_job" "this" {
      name = var.job_name
      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
    }
    
  12. 如果您要建立作業,請建立名為 job.auto.tfvars 的另一個檔案,並將下列內容新增至檔案。 此檔案包含自訂作業組態的變數值。

    job_name = "My Job"
    

步驟 2:執行設定

在此步驟中,您會執行 Terraform 設定,將叢集、筆記本和作業部署到您的 Azure Databricks 工作區。

  1. 執行 命令,查看您的 Terraform 設定是否有效 terraform validate 。 如果回報任何錯誤,請加以修正,然後再次執行命令。

    terraform validate
    
  2. 執行 命令,在 Terraform 實際執行之前, terraform plan 請檢查 Terraform 會在工作區中執行哪些動作。

    terraform plan
    
  3. 執行 命令,將叢集、筆記本和作業部署至您的工作區 terraform apply 。 當系統提示您部署時,輸入 yes 並按 Enter

    terraform apply
    

    Terraform 會部署專案中指定的資源。 部署這些資源 (特別是叢集) 可能需要幾分鐘的時間。

步驟 3:探索結果

  1. 如果您已建立叢集,請在 命令的 terraform apply 輸出中,複製 旁邊的 cluster_url 連結,並將其貼到網頁瀏覽器的網址列中。

  2. 如果您已建立筆記本,請在命令的 terraform apply 輸出中,複製 旁邊的 notebook_url 連結,然後將它貼到網頁瀏覽器的網址列中。

    注意

    使用筆記本之前,您可能需要自訂其內容。 請參閱有關如何自訂筆記本的相關檔。

  3. 如果您已建立作業,請在 命令的 terraform apply 輸出中,複製 旁邊的 job_url 連結,並將它貼到網頁瀏覽器的網址列中。

    注意

    執行筆記本之前,您可能需要自訂其內容。 如需如何自訂筆記本的相關檔,請參閱本文開頭的連結。

  4. 如果您已建立作業,請執行作業,如下所示:

    1. 按一下作業頁面上 的 [立即執行 ]。
    2. 作業完成執行之後,若要檢視作業執行的結果,請在作業頁面上 的 [已完成執行] (過去 60 天) 清單中,按一下 [ 開始時間 ] 資料行中的最近時間專案。 [ 輸出 ] 窗格會顯示執行筆記本程式碼的結果。

步驟 4:清除

在此步驟中,您會從工作區中刪除上述資源。

  1. 執行 命令,在 Terraform 實際執行之前, terraform plan 請檢查 Terraform 會在工作區中執行哪些動作。

    terraform plan
    
  2. 執行 命令,從工作區 terraform destroy 刪除叢集、筆記本和作業。 當系統提示您刪除時,輸入 yes 並按 Enter

    terraform destroy
    

    Terraform 會刪除專案中指定的資源。