返回文章列表

Terraform 自動化佈署 DLT 管道實踐

本文介紹如何使用 Terraform 和 VS Code 佈署、維護和管理 DLT 管道,涵蓋設定 VS Code、建立 Terraform 專案、定義 Terraform 資源、設定 Unity Catalog 儲存位置、定義 DLT 管道、設定工作流程以及輸出工作流程 URL 等步驟。此外,文章還探討了

資料工程 雲端服務

隨著資料應用程式日益複雜,自動化佈署和管理資料管線變得至關重要。本文將探討如何利用 Terraform 和 VS Code 建立和佈署 Delta Live Tables (DLT) 管道到 Databricks 工作區,實作基礎設施即程式碼 (IaC) 的最佳實踐。同時,也將介紹 Databricks 資產包 (DAB) 作為另一種佈署方式,並比較其與 Terraform 的差異,提供更全面的資料管線佈署策略。文章將逐步引導讀者完成設定開發環境、撰寫 Terraform 組態檔案、定義 DLT 管道、設定工作流程以及使用 DAB 佈署等關鍵步驟,並提供程式碼範例和詳細說明,幫助讀者快速上手並應用於實際專案。

圖表翻譯:

此圖示呈現了使用 Terraform 和 CI/CD 工具自動佈署 DLT 管道的流程。它描述了從建立新功能分支到將變更佈署到 Databricks 工作區的整個過程,包括建置管道和釋出管道的觸發。

使用 Terraform 佈署、維護和管理 DLT 管道

練習:使用 VS Code 佈署 DLT 管道

在本練習中,我們將使用流行的程式碼編輯器 Visual Studio Code(VS Code)來撰寫新的 Terraform 組態檔案,以佈署 DLT 管道到目標 Databricks 工作區。VS Code 因其易用性、輕量級記憶體佔用、友好的程式碼導航、語法突顯和程式碼重構等功能而廣受歡迎。此外,VS Code 還具有豐富的擴充套件社群。

設定 VS Code

首先,從官方網站下載並安裝 VS Code。安裝完成後,我們需要安裝 HashiCorp 提供的 Terraform 擴充套件。這個擴充套件提供了 Terraform 語法突顯、自動完成、程式碼格式化等功能,能夠大大簡化 Terraform 組態檔案的開發過程。

建立新的 Terraform 專案

  1. 建立一個新的目錄,用於存放本練習的相關檔案:
    $ mkdir chapter_8_hands_on
    $ cd chapter_8_hands_on
    
  2. 在該目錄下建立一個空的 Terraform 組態檔案,命名為 main.tf
    $ touch main.tf
    
  3. 可以選擇性地從本章的 GitHub 倉函式庫克隆範例專案。然後,在 VS Code 中開啟該目錄。

定義 Terraform 資源

接下來,我們將擴充套件本章開頭介紹的 Terraform 範例。首先,在 databricks_notebook 資源定義中新增第二個資料集,以建立一個包含兩個資料集的資料管道:一個 bronze 層和一個 silver 層。更新 main.tf 檔案中的 databricks_notebook 資源定義如下:

resource "databricks_notebook" "dlt_pipeline_notebook" {
  path = "${data.databricks_current_user.my_user.home}/chp_8_terraform/taxi_trips_pipeline.py"
  ...
  .load(path))
  @dlt.table(
    name="yellow_taxi_silver",
    comment="Financial information from incoming taxi trips."
  )
  @dlt.expect_or_fail("valid_total_amount", "total_amount > 0.0")
  def yellow_taxi_silver():
    return (dlt.readStream("yellow_taxi_bronze")
      .withColumn("driver_payment", F.expr("total_amount * 0.40"))
      .withColumn("vehicle_maintenance_fee", F.expr("total_amount * 0.05"))
      .withColumn("adminstrative_fee", F.expr("total_amount * 0.1"))
      .withColumn("potential_profits", F.expr("total_amount * 0.45")))
  EOT
}

程式碼解析

上述程式碼定義了一個名為 yellow_taxi_silver 的資料集,該資料集根據 yellow_taxi_bronze 資料集進行轉換,新增了四個新的欄位:driver_paymentvehicle_maintenance_feeadminstrative_feepotential_profits。這些欄位是透過對 total_amount 欄位進行計算得到的。

  1. @dlt.table 裝飾器:用於定義一個 DLT 資料表。
  2. @dlt.expect_or_fail 裝飾器:用於定義資料品品檢查規則,如果檢查失敗,則管道執行將失敗。
  3. dlt.readStream("yellow_taxi_bronze"):讀取 yellow_taxi_bronze 資料集的資料流。
  4. .withColumn:新增新的欄位到資料集中。
  5. F.expr:使用 SQL 表示式來計算新的欄位值。

透過這些步驟,我們成功地使用 Terraform 和 VS Code 佈署了一個包含兩個資料集的 DLT 管道。接下來,我們可以進一步探索如何維護和管理這個管道。

使用 VS Code 佈署 DLT 管道的手把手練習

設定 Unity Catalog 儲存位置

在建立新的 DLT 管道之前,我們需要在 Unity Catalog 中定義一個儲存資料集的位置。請將以下目錄和架構資源定義加入到 main.tf 檔案的底部:

resource "databricks_catalog" "dlt_target_catalog" {
  name    = "chp8_deploying_pipelines_w_terraform"
  comment = "The target catalog for Taxi Trips DLT pipeline"
}

resource "databricks_schema" "dlt_target_schema" {
  catalog_name = databricks_catalog.dlt_target_catalog.id
  name         = "terraform_demo"
  comment      = "The target schema for Taxi Trips DLT pipeline"
}

內容解密:

  • databricks_catalog 資源用於在 Unity Catalog 中建立一個新的目錄。
  • databricks_schema 資源用於在指定的目錄中建立一個新的架構。
  • comment 欄位用於提供相關資源的描述。

定義 DLT 管道

現在我們已經更新了包含 DLT 管道定義的源 notebook,並且在 Unity Catalog 中有了一個儲存資料集的位置。接下來,我們可以定義一個 DLT 管道。請將以下管道定義加入到 main.tf 檔案中:

resource "databricks_pipeline" "taxi_trips_pipeline" {
  name = "Taxi Trips Pipeline"

  library {
    notebook {
      path = "${data.databricks_current_user.my_user.home}/chp_8_terraform/taxi_trips_pipeline.py"
    }
  }

  cluster {
    label = "default"
    num_workers = 2
    autoscale {
      min_workers = 2
      max_workers = 4
      mode         = "ENHANCED"
    }
    driver_node_type_id = "i3.2xlarge"
    node_type_id        = "i3.xlarge"
  }

  continuous = false
  development = true
  photon      = false
  serverless  = false
  catalog     = databricks_catalog.dlt_target_catalog.name
  target      = databricks_schema.dlt_target_schema.name
  edition     = "ADVANCED"
  channel     = "CURRENT"
}

內容解密:

  • databricks_pipeline 資源用於定義一個 DLT 管道。
  • library 區塊指定了包含 DLT 管道定義的 notebook 路徑。
  • cluster 區塊定義了用於管道更新和維護任務的預設叢集組態。
  • 其他引數如 continuousdevelopmentphotonserverless 等用於控制管道的執行時組態。

設定工作流程

接下來,我們需要協調對 DLT 管道的更新,以便能夠觸發重複排程的執行、設定警示通知或設定逾時閾值。請將以下工作流程定義加入到 main.tf 檔案的底部:

resource "databricks_job" "taxi_trips_pipeline_job" {
  name        = "Taxi Trips Pipeline Update Job"
  description = "Databricks Workflow that executes a pipeline update of the Taxi Trips DLT pipeline."

  job_cluster {
    job_cluster_key = "taxi_trips_pipeline_update_job_cluster"
    new_cluster {
      num_workers        = 2
      spark_version      = "15.4.x-scala2.12"
      node_type_id       = "i3.xlarge"
      driver_node_type_id = "i3.2xlarge"
    }
  }

  task {
    task_key = "update_taxi_trips_pipeline"
    pipeline_task {
      pipeline_id = databricks_pipeline.taxi_trips_pipeline.id
    }
  }

  trigger {
    pause_status = "PAUSED"
    periodic {
      interval = "1"
      unit     = "HOURS"
    }
  }
}

內容解密:

  • databricks_job 資源用於定義一個工作流程,該工作流程執行 DLT 管道的更新。
  • job_cluster 區塊定義了用於執行工作流程任務的叢集組態。
  • task 區塊指定了更新 DLT 管道的任務。
  • trigger 區塊設定了工作流程的觸發器,目前設定為暫停狀態,但組態為每小時執行一次。

輸出工作流程 URL

最後,我們希望輸出已佈署資源的工作流程 URL,以便能夠輕鬆地從瀏覽器開啟工作流程 UI。請將以下輸出定義加入到 main.tf 檔案中:

output "workflow_url" {
  value = databricks_job.taxi_trips_pipeline_job.url
}

內容解密:

  • output 用於輸出特定資源的屬性值,在此例中輸出的是工作流程的 URL。

佈署 Terraform 專案

在開始佈署新資源之前,第一步是初始化 Terraform 專案。請在父目錄中執行 Terraform init 命令,可以透過 VS Code 命令面板或 shell 命令列完成:

$ terraform init

接下來,預覽 Terraform 檔案中的變更,執行 Terraform plan 命令以檢視預計的基礎設施變更:

$ terraform plan

總共應該會建立五個新資源,包括代表包含 DLT 管道定義的 notebook 的 databricks_notebook 資源、目標 Unity Catalog 的目錄和架構、databricks_pipeline 資源(代表我們的 DLT 管道),以及代表將觸發管道更新的工作流程的 databricks_job 資源。

在驗證計劃後,我們現在可以將我們的 DLT 管道佈署到 Databricks 工作區。接下來,執行 Terraform apply 命令以佈署新的基礎設施變更到我們的工作區:

$ terraform apply

一旦所有資源變更都已套用,您應該會看到 Terraform 輸出 Databricks 工作流程的 URL。

利用Databricks資產包簡化資料管線佈署

技術需求

Databricks資產包簡介

DAB提供了一種簡便的方式來開發您的資料和人工智慧(AI)專案,並附帶YAML後設資料,用於宣告相關的基礎設施。DAB為資料工程師提供了一種以程式設計方式驗證、佈署和測試目標工作區中的Databricks資源的方法。這可能包括佈署工作區資產,如Delta Live Tables(DLT)管線、工作流程、筆記本等。DAB還提供了一種方便的方式,使用可重複使用的範本(我們將在初始化資產包使用範本部分中介紹)來開發、封裝和佈署機器學習工作負載,稱為MLOps堆積疊。

DAB與Terraform的比較

DAB與Terraform有一些相似之處,因為它們都是基礎設施即程式碼(IaC)工具,能夠讓使用者定義雲端資源並以雲端無關的方式佈署這些資源。然而,它們之間也有許多差異。讓我們比較一下DAB和Terraform之間的相似性和差異,以更好地瞭解何時選擇哪種工具來滿足您的組織需求。

DAB組態檔案的元素

在DAB的核心是一個名為databricks.yml的YAML組態檔案。此組態檔案為工程師提供了一個入口點,用於組態其專案資源的佈署。該檔案由許多可組合的構建塊組成,這些構建塊告訴Databricks命令列介面(CLI)要佈署到目標Databricks工作區的內容以及如何組態每個資源。每個構建塊接受不同的引數來組態該元件。

databricks.yml檔案的對映

這些對映可以是各種Databricks資源。例如,DAB組態檔案可以包含以下對映的任意組合:

對映名稱是否必填描述
bundle包含當前資產包的頂級資訊,包括Databricks CLI版本、現有叢集識別符號和git設定。
variables包含在執行DAB佈署期間動態填充的全域變數。
workspace用於指定非預設工作區位置,例如根儲存、成品儲存和檔案路徑。
permissions包含有關授予已佈署資源的許可權的資訊。
resources指定要佈署的Databricks資源以及如何組態它們。
artifacts指定在佈署過程中將生成的佈署成品,例如Python .whl檔案。
include指定其他組態檔案的相對檔案路徑globs列表。這是將DAB組態檔案分成幾個子組態檔案的好方法。
sync指定在佈署過程中要包含或排除的相對檔案路徑globs列表。
targets指定有關上下文的資訊,以及有關工作流程、管線和成品的詳細資訊。

簡單的DAB組態檔案範例

讓我們看一個簡單的DAB組態檔案,以便熟悉一些基礎知識。以下範例將建立一個名為Hello, World!的新Databricks工作流程,該工作流程將執行一個列印預出簡單而流行的表示式Hello, World!的筆記本:

bundle:
  name: hello_dab_world
resources:
  jobs:
    hello_dab_world_job:
      name: hello_dab_world_job

內容解密:

此YAML組態檔案定義了一個名為hello_dab_world的DAB。它包含一個名為hello_dab_world_job的工作流程,該工作流程被定義在resources下的jobs部分。此工作流程目前僅包含一個名為hello_dab_world_job的作業。

程式碼解析

這段YAML程式碼展示瞭如何使用DAB組態檔案來定義Databricks資源。在這個例子中,我們定義了一個簡單的工作流程,其中包含一個名為hello_dab_world_job的作業。要執行此工作流程,需要進一步組態作業的詳細資訊,例如要執行的筆記本或指令碼。

# 定義一個名為hello_dab_world的資產包
bundle:
  name: hello_dab_world

# 定義資源部分
resources:
  # 在resources下定義jobs部分
  jobs:
    # 定義一個名為hello_dab_world_job的作業
    hello_dab_world_job:
      # 設定作業名稱為hello_dab_world_job
      name: hello_dab_world_job

內容解密:

  1. bundle: 定義了資產包的基本資訊,包括名稱。
  2. resources: 定義了要佈署的Databricks資源。
  3. jobs: 在resources下定義了作業部分,可以包含多個作業。
  4. hello_dab_world_job: 定義了一個具體的作業,名稱為hello_dab_world_job

要使這個範例完整,需要進一步定義作業的具體內容,例如要執行的筆記本或指令碼。這部分內容將在後續章節中詳細介紹。