使用 Databricks Lakehouse 构建现代数据应用程序——使用 Terraform 部署、维护和管理 DLT 管道

264 阅读23分钟

在本章中,我们将探讨如何使用像 Terraform 这样的自动化工具,在 Databricks 中将数据管道表示为代码,通常称为基础设施即代码(IaC)。我们将学习如何使用流行的代码编辑器(如 VS Code)设置本地 Terraform 开发环境,以便我们可以尝试将不同的资源部署到 Databricks 工作区。接下来,我们将深入了解如何使用 Terraform 表示数据管道,并如何配置 Delta Live Tables(DLT)管道的不同方面。我们还将探讨如何自动化 IaC 的验证和部署到不同的 Databricks 工作区,包括生产工作区。最后,我们将检查行业最佳实践和未来的考虑因素。

本章将涵盖以下主要内容:

  • 介绍 Databricks 的 Terraform 提供程序
  • 设置本地环境
  • 使用 Terraform 配置 DLT 管道
  • 自动化 DLT 管道部署
  • 动手实验 - 使用 VS Code 部署 DLT 管道

技术要求

要跟随本章提供的示例,您需要具有 Databricks 工作区权限来创建和启动一个通用集群,以便导入并执行本章的配套笔记本。所有代码示例可以从本章的 GitHub 仓库下载,地址为:GitHub 仓库。本章将创建并运行几个新笔记本,还将使用该产品的高级版运行新的 DLT 管道,预计消耗大约 10-15 个 Databricks 单位(DBUs)。

介绍 Databricks 的 Terraform 提供程序

Terraform 是一个开源的部署自动化工具,可用于以可重复和可预测的方式自动化云基础设施的部署。Terraform 之所以成为如此受欢迎的部署工具,是因为它支持将基础设施部署到三大云提供商:Amazon Web Services(AWS)、Azure 和 Google Cloud Platform(GCP)。Terraform 以定义基础设施即代码(IaC)的概念为中心,即不是手动部署云组件,如网络对象、虚拟机或存储容器,而是通过代码文件来表达这些组件。此外,Terraform 文件是基于配置驱动的。云管理员不再关注如何部署基础设施,而是专注于通过配置来表达环境之间的变化。最后,Terraform 会维护架构的状态,这意味着该工具将跟踪云资源的状态,并在每次执行 Terraform 配置文件时相应地更新状态。

最后,Terraform 文件可以直接从本地机器执行,使您能够远程与云资源进行交互。

image.png

Terraform 配置文件定义云基础设施并将其应用于云提供商,同时基础设施的状态会同步回本地环境。此外,Databricks 提供了一个 Terraform 提供程序,用于将 Databricks 工作区和工作区对象部署到主要云提供商。

Terraform 提供程序是 Terraform 工具的一个插件,允许用户与特定的 API 进行交互。在这个例子中,Terraform 提供程序与 Databricks REST API 进行交互,允许工作区管理员自动化部署即使是最复杂的数据处理环境。

使用 Terraform 自动化部署数据管道在组织中的许多优点包括:

  • 它使在主要云提供商之间部署基础设施变得容易,这使得如果需要,可以轻松迁移云环境。
  • 它通过关注定义配置而不是手动部署和维护数据管道,使得扩展到数百个数据管道变得容易。
  • 管道定义简洁,允许云管理员专注于表达应当改变的内容,而不是如何部署基础设施。

让我们看看定义 Databricks 资源并将其应用于目标工作区有多么容易。

设置本地 Terraform 环境

在我们开始将数据管道对象部署到 Databricks 工作区之前,我们需要安装 Terraform 命令行工具(CLI)。如果您还没有安装,您需要从 HashiCorp 网站(developer.hashicorp.com/terraform/i…)免费下载 Terraform CLI。

接下来,我们要将 Terraform 配置文件组织到一个目录中。我们将创建一个名为 chp8_databricks_terraform 的新目录。

在新创建的目录中,我们将创建一个全新的 Terraform 配置文件,在其中定义我们的数据管道和其他相关的工作区对象。创建一个新文件,并命名为 main.tf

重要提示 Terraform 配置文件使用 Terraform 语言,并以 .tf 扩展名结尾。

导入 Databricks Terraform 提供程序

使用 Terraform 部署 Databricks 工作区对象的第一步是导入 Databricks Terraform 提供程序。如果这是您第一次使用 Terraform 提供程序,Terraform 将负责从 Terraform Registry 下载 Databricks 提供程序。Terraform Registry 是一个公共中心,提供下载第三方提供程序、模块和安全策略,帮助开发 Terraform 配置文件以部署云基础设施。

在新的 Terraform 配置文件 main.tf 顶部添加以下代码片段:

terraform {
  required_providers {
    databricks = {
    source = "databricks/databricks"
    }
  }
}

这段代码将指示 Terraform CLI 工具从 Terraform Registry 下载并导入名为 databricks 的 Terraform 提供程序,该程序由 Databricks 组织发布。

现在我们已经导入了 Databricks Terraform 提供程序,我们可以开始将数据管道对象部署到 Databricks 工作区。但在此之前,我们必须首先对我们的 Databricks 工作区进行身份验证,以便进行更改,例如创建新的 DLT 管道。

配置工作区认证

如您所记得,Databricks Terraform 提供程序将与 Databricks REST API 进行交互。因此,使用 Terraform 时可以应用与 Databricks REST API 认证和进行工作区更改时相同的认证机制。

总的来说,使用 Terraform 提供程序认证 Databricks 工作区的方法有大约九种(最新的列表可以在此查看:registry.terraform.io/providers/d…

  • 使用工作区管理员的用户名和密码
  • 使用 Databricks 个人访问令牌(PAT)
  • 使用 Azure CLI 或 Google Cloud CLI
  • 如果使用 Azure 云提供商,使用服务主体或托管服务身份
  • 使用 Databricks CLI(用户到机器认证)

重要提示 由于我们在进行本地开发和测试,在以下示例中,我们将使用 Databricks CLI 生成 OAuth 令牌,并手动登录到我们的 Databricks 工作区。然而,对于生产部署,建议将工作区凭证安全存储在像 Azure Key Vault、AWS Secrets Manager 或 HashiCorp Vault 等秘密管理器中。

存储与 Terraform 一起使用的认证令牌有几种选择——直接在 Terraform 配置文件中作为 Databricks 提供程序导入的一部分,或者存储在本地机器的配置文件中。我们建议使用后者,以避免在将代码工件提交到代码仓库时意外暴露凭证。最简单的方式是使用 Databricks CLI 填充该配置文件。

Databricks CLI 支持 Windows、Linux 或 macOS 操作系统,使其成为一个跨平台兼容且多功能的工具。如果您的本地机器使用 macOS 或 Linux 操作系统,您可以通过使用 Homebrew 包管理器在命令行中下载 Databricks CLI。或者,您也可以轻松升级现有 Databricks CLI 安装的版本。例如,以下命令将在 Mac 上使用 Homebrew 安装或升级现有 Databricks CLI 安装:

$ brew tap databricks/tap
$ brew install databricks

在 Windows 机器上,您可以使用流行的包管理器 winget 安装 Databricks CLI(winget 文档)。以下命令将使用 winget 工具下载并安装 Databricks CLI:

$ winget search databricks
$ winget install Databricks.DatabricksCLI

下载完成后,您可以通过执行 Databricks CLI 中的 configure 命令来配置认证:

$ databricks configure

当将 Terraform 配置文件应用到目标环境时,Terraform CLI 将首先检查配置文件中是否直接提供了认证详情。否则,Terraform CLI 将查找本地 Databricks 配置文件,该文件存储在名为 .databrickscfg 的隐藏文件中,该文件位于您的用户主文件夹下。

您还可以指定一个配置文件名称,当您有多个 Databricks 工作区并需要在不同的工作区之间部署基础设施组件时,这非常有用。使用配置文件,您可以单独存储认证详情,并在部署期间轻松引用它们。有关如何创建/测试配置文件的更多信息,您可以在此了解:Databricks CLI 配置文件文档

定义 DLT 管道源笔记本

在下一个示例中,我们将定义一个笔记本,包含一个简单的 DLT 管道的起始部分,并将该笔记本部署到目标 Databricks 工作区中的用户工作区目录中。

为了构建部署笔记本的工作区位置,我们需要获取当前的 Databricks 用户。为了避免硬编码此值,我们可以使用 databricks_current_user 数据源,它在部署时检索当前用户的 Databricks 用户名。在 main.tf 文件中添加以下配置块:

data "databricks_current_user" "my_user" {}

接下来,我们将使用 databricks_notebook 资源定义一个新的 Python 笔记本,并使用前面的数据源构建笔记本路径。由于笔记本相对简单,只包含一个 DLT 数据集定义,我们将内联定义笔记本内容。将以下配置块添加到 main.tf 文件中:

resource "databricks_notebook" "dlt_pipeline_notebook" {
  path = "${data.databricks_current_user.my_user.home}/chp_8_terraform/my_simple_dlt_pipeline.py"
  language = "PYTHON"
  content_base64 = base64encode(<<-EOT
    import dlt
    @dlt.table(
        comment="位于`/databricks-datasets/`的原始 NYC 出租车数据集"
    )
    def yellow_taxi_raw():
        path = "/databricks-datasets/nyctaxi/tripdata/yellow"
        schema = "vendor_id string, pickup_datetime timestamp, dropoff_datetime timestamp, passenger_count integer, trip_distance float, pickup_longitude float, pickup_latitude float, rate_code integer, store_and_fwd_flag integer, dropoff_longitude float, dropoff_lattitude float, payment_type string, fare_amount float, surcharge float, mta_tax float, tip_amount float, tolls_amount float, total_amount float"
        return (spark.readStream
                    .schema(schema)
                    .format("csv")
                    .option("header", True)
                    .load(path))
    EOT
  )
}

最后,向 main.tf 配置文件添加最后一个块,打印已部署笔记本的 URL:

output "notebook_url" {
  value = databricks_notebook.dlt_pipeline_notebook.url
}

点击保存以保存配置文件。在终端窗口中,导航到包含 main.tf 配置文件的目录。

应用工作区更改

首先应该运行的命令是 terraform init 命令,该命令执行几个初始化步骤,为使用 Terraform 部署云资源准备当前工作目录。在终端窗口或 shell 提示符下执行以下命令:

terraform init

接下来,Terraform CLI 为我们提供了一种在应用更改之前验证 Terraform 配置文件影响的方式。执行 validate 命令:

terraform validate

最后,我们可以通过列出 Terraform 计划中的所有预定更改来查看拟议的基础设施更改。执行以下命令查看拟议的 Terraform 计划:

terraform plan

您会注意到,计划中将定义一个资源。在这种情况下,它将是包含我们 DLT 数据集定义的新 Databricks 笔记本。

一旦验证计划看起来没问题,我们就可以将更改应用到目标 Databricks 工作区。通过执行 apply 命令来应用 Terraform 计划:

terraform apply

输出将是新创建的笔记本的完整 URL。复制输出的 URL 并粘贴到浏览器窗口中。验证是否有一个新的笔记本,默认编程语言为 Python,其中包含一个单一的笔记本单元,定义了一个单一的 DLT 数据集 yellow_taxi_raw

恭喜!您已经编写了您的第一个 Terraform 配置文件,并且已经为自动化在不同环境中部署 Databricks 资源奠定了良好的基础。在接下来的部分,我们将扩展前面的示例,看看如何使用 Databricks Terraform 提供程序将 DLT 管道部署到工作区。

使用 Terraform 配置 DLT 管道

我们将使用 Databricks Terraform 提供程序中的 databricks_pipeline 资源,将 DLT 管道部署到目标 Databricks 工作区。databricks_pipeline 资源是我们 Terraform 配置文件的主要构建模块。在这个 Terraform 资源中,我们可以指定许多不同的配置选项,这些选项会影响 DLT 管道的部署。例如,我们可以配置 DLT 的生产版、目标 Unity Catalog 位置、库依赖关系、更新集群大小等。让我们深入了解具体的配置,以便更好地理解您在部署的 DLT 管道上拥有的控制类型。

使用 Databricks Terraform 提供程序定义 DLT 管道的配置和行为时,会用到几个参数。为了更好地了解这些参数的类型,以下部分涵盖了 Databricks Terraform 提供程序中所有可用的参数(最新版本可以在此查看:Terraform 文档)。

一般来说,databricks_pipeline 的参数可以归类为三大类:

  • 运行时配置:name、channel、development、continuous、edition、photon、configuration 和 library
  • 管道计算配置:cluster
  • 管道数据集存储配置:catalog、target 和 storage

让我们逐一详细了解每个参数,以便更好地理解我们的 Terraform 配置如何影响目标 DLT 管道。

name

name 参数为 DLT 管道分配一个字母数字名称,用于标识该管道。name 参数应该是一个字符串,可以包含混合大小写字符、数字、空格和特殊字符(包括 emoji 字符)。此外,管道名称参数不一定需要是唯一的;Databricks Terraform 提供程序并不会强制执行名称的唯一性。在创建 DLT 管道时,Databricks 数据智能平台会为每个管道分配一个唯一的管道标识符,因此 name 参数仅作为数据工程师区分 DLT 管道与其他管道的一种方便方式。

notification

notification 参数用于指定在特定管道事件期间将接收电子邮件通知的收件人列表。会触发通知的 DLT 管道事件类型包括 on-update-successon-update-failureon-update-fatal-failureon-flow-failure

channel

channel 参数控制 DLT 管道更新集群应使用的 Databricks 运行时类型。只有两个选项可供选择:CURRENTPREVIEWCURRENT 选择最新的稳定版 Databricks 运行时,并且是默认选项。如果您的 DLT 管道在开发环境中运行,并且您希望尝试即将推出的性能功能和优化,尚未进入当前 Databricks 运行时,您可以选择 PREVIEW

development

development 参数是一个布尔标志,用于控制是否希望在开发模式下执行 DLT 管道。当设置为 true 时,Terraform 将部署一个 DLT 管道,且管道模式设置为开发模式。此设置也将在 DLT UI 中通过右上角的切换按钮反映出来。

image.png

同样地,当该参数设置为false时,Terraform将把管道模式设置为生产模式。如果你还记得第二章提到的,在开发模式下,DLT在遇到运行时异常时不会重试管道更新,并且会保持更新集群的运行,帮助数据工程师诊断和修复错误,从而缩短调试周期。

continuous

continuous参数是一个布尔标志,控制管道更新执行的频率。当设置为true时,Terraform将部署一个DLT管道,该管道将在DLT管道内持续更新数据集。同样地,当设置为false时,DLT管道将以触发执行模式部署。在这种执行模式下,数据工程师需要通过点击DLT UI上的“启动”按钮或调用Pipelines REST API来触发管道更新的开始。

edition

edition参数选择在部署DLT管道时使用的产品版本。可以选择的版本只有三种:CORE、PRO和ADVANCED。如果你还记得第二章提到的,产品版本选择了在运行DLT管道时要启用的功能集。因此,管道的定价会根据启用的功能数量来反映。例如,PRO产品版本将使数据工程师能够使用期望值来强制执行数据质量,但也会产生最高的运营成本。另一方面,CORE产品版本可以用于将传入数据追加到流式表中,并且更新所需的操作费用最少。

photon

photon参数是一个布尔标志,控制是否使用Photon处理引擎来更新DLT管道。当设置为true时,Terraform将部署一个DLT管道,该管道的更新集群启用了Photon引擎。在数据集更新过程中,DLT管道可以利用这个快速的矢量化处理引擎,使得连接、聚合、窗口操作和排序比默认集群要快。设置为false时,DLT将使用传统的Catalyst引擎在Spark中创建更新集群。由于更快的处理和改进的性能,启用Photon执行会导致更高的DBU定价。

configuration

configuration参数允许数据工程师在部署DLT管道时使用可选的运行时配置。configuration参数是一个可选的键值对列表。这个参数可以用来填充环境变量、云存储位置或集群关闭设置等。

library

library参数可以用来安装数据工程师在更新DLT管道时可能依赖的集群库。library参数还支持引用本地笔记本或任意文件的依赖,如果数据工程师希望使用本地文件而不是构建工件来包含依赖的代码工件。例如,以下library块可以用于包含一个用户在其工作区中定义的自定义日期工具,作为Python文件:

library {
  notebook {
    path = "/Users/<username>/common/utils/date_utils.py"
  }
}

cluster

cluster参数控制管道在更新、维护活动或默认集群类型时使用的集群。如果未指定集群块,DLT将创建一个默认集群用于应用管道的数据集更新。此外,cluster参数还将包含一个mode参数,你可以在其中指定使用的自动缩放类型。如果你还记得第二章中提到的,DLT有两种自动缩放模式:LEGACYENHANCED。例如,以下配置将创建一个更新集群,该集群将在ENHANCED自动缩放算法下,最少从三个工作节点自动扩展到最多八个工作节点:

cluster {
  node_type_id = "i3.xlarge"
  autoscale {
    min_workers = 3
    max_workers = 8
    mode = "ENHANCED"
  }
}

catalog

catalog参数决定在Unity Catalog中存储DLT管道输出数据集的目录。当DLT管道执行时,管道中定义的数据集需要指定目标位置。你可以指定一个目录和模式的组合(在下一节中介绍的target),或者可以指定一个云存储位置,但不能同时指定两者。这个参数与下一个storage参数是互斥的。或者,数据工程师可以继续将DLT管道的数据集存储在传统的Hive Metastore中,配置如下:

catalog {
  name = "hive_metastore"
}

重要说明
如果在Terraform配置文件中更改了catalogstorage参数,并且这些更改被应用,Terraform将会使用新更改重新创建整个DLT管道。一旦管道部署完成,无法在原始DLT管道中更新这些值。

target

target参数指定在Unity Catalog或传统Hive Metastore中存储DLT管道输出数据集的模式。该参数与前面的catalog参数组合,指定Unity Catalog中的完整模式或传统Hive Metastore中的模式。数据工程师可以选择使用catalogtarget参数设置的值,作为查询DLT管道中间数据集的便捷方式。这通常用于数据验证、调试或数据清洗等常见任务。

storage

storage参数可以用来指定一个云存储位置,用于存储DLT管道的输出数据集和其他相关元数据。需要注意的是,这个参数与前面的catalog参数是互斥的。storage参数可以包含一个完全限定的存储位置路径、卷位置或Databricks文件系统(DBFS)中的位置。例如,以下配置块将创建一个DLT管道,其输出数据集将存储在DBFS中:

storage {
  path = "/pipelines/my-dlt-pipeline-output/"
}

重要说明
storagecatalog参数互相排斥。在编写Terraform配置文件时,你只能指定一个。

到此为止,你应该对如何使用Databricks提供的Terraform资源声明DLT管道有了足够的信心。你也应该更清楚不同的配置选项,如何定制目标DLT管道。接下来,我们将探讨如何使用现有的版本控制系统自动化部署DLT管道,以便在最新更改可用时,能够在目标工作区之间同步这些更改。

自动化DLT管道部署

Terraform可以与自动化的持续集成/持续部署(CI/CD)工具结合使用,如GitHub Actions或Azure DevOps Pipelines,以自动将代码更改部署到Databricks工作区。由于Terraform是跨平台的,目标Databricks工作区可以位于主要云提供商之一:GCP、AWS或Azure。这使得你的开发团队能够在一套代码工件中维护基础设施,同时又足够灵活,可以将相同的资源应用于不同的云提供商。

接下来,我们将介绍一个典型的CI/CD流程,使用Databricks的Terraform提供程序将Databricks资源部署到目标工作区。CI/CD流程将包含两个自动化构建管道——一个用于验证在功能分支中所做的更改,另一个用于将已经批准并合并到主代码分支中的更改部署到Databricks工作区。

首先,团队成员创建一个新的功能分支,用于跟踪他们组织中的基础设施即代码(IaC)代码库的更改。一旦完成,工程师将打开一个拉取请求,请求一名或多名团队成员审核更改、留下反馈,并批准或拒绝更改。打开拉取请求后,构建管道将被触发运行,它将检出功能分支,使用Terraform init命令初始化当前工作目录,使用Terraform validate命令验证Terraform计划,并生成一个Terraform计划的输出。可选地,这个Terraform计划可以作为评论自动包含在拉取请求中,供同行审核。

当拉取请求得到团队成员的批准后,功能分支可以合并到主代码仓库分支中——简而言之,就是合并到主分支。

一旦功能分支合并到主分支,构建发布管道将被触发运行。构建发布管道将检出主分支的最新副本,并使用Terraform apply命令应用更改。在应用Terraform计划后,组织基础设施的新更改将反映在目标Databricks工作区中。

image.png

到现在为止,你应该已经完全理解了如何使用像Azure DevOps这样的工具,通过Terraform同步基础设施更改,设计自动化的Databricks部署。接下来,让我们将前面章节中学到的所有内容结合起来,使用典型的开发环境将我们的DLT管道部署到目标Databricks工作区。

实践练习 - 使用VS Code部署DLT管道

在这个实践练习中,我们将使用流行的代码编辑器Visual Studio Code(VS Code)编写新的Terraform配置文件,用于将DLT管道部署到目标Databricks工作区。VS Code因其易用性、轻量级的内存占用、友好的代码导航、语法高亮、代码重构以及丰富的扩展社区而获得了极大的欢迎。此外,VS Code是围绕开源社区构建的,意味着它是免费提供下载和使用的。更重要的是,VS Code是一个跨平台的代码编辑器,支持Windows、macOS和Linux操作系统。在这个实践练习中,我们将使用社区扩展之一——HashiCorp为VS Code开发的Terraform插件,来协助开发Terraform配置文件。例如,VS Code的Terraform插件具有Terraform语法高亮、自动补全、代码格式化、从VS Code命令面板访问Terraform命令等功能,整体上为在VS Code中浏览Terraform配置文件提供了轻松的体验,帮助我们部署Databricks工作区对象。

设置VS Code

VS Code可以从其官方网站下载,网址为 code.visualstudio.com/download。如果你还没有安装VS Code,选择与本地机器操作系统匹配的安装程序下载。根据你的网络连接速度,下载过程可能需要几分钟。下载完成后,解压ZIP文件以显示下载的内容。接着,双击应用程序文件“Visual Studio Code”以启动代码编辑器。或者,你可以将应用程序文件移动到本地操作系统的“应用程序”目录。

接下来,我们将安装HashiCorp提供的Terraform扩展。在一个浏览器窗口中,访问Visual Studio Marketplace网站中的Terraform扩展页面:marketplace.visualstudio.com/items?itemN…。或者,你也可以在VS Code的Marketplace搜索框中搜索该扩展。点击“安装”按钮,下载并安装VS Code的Terraform扩展。

image.png

你可能会被提示允许你的网页浏览器打开本地机器上的VS Code应用程序。如果是这样,点击“允许”按钮以打开VS Code并安装扩展。扩展将在几分钟内下载并安装完成。安装完成后,你应该能够在VS Code的左侧导航栏看到HashiCorp Terraform的菜单项。

image.png

现在,Terraform扩展已成功安装,当代码编辑器检测到Terraform文件时,扩展将自动激活。你可以通过在打开的Terraform文件的右下角看到Terraform图标来验证扩展是否已激活。

创建一个新的Terraform项目

让我们为实践练习创建一个新的目录:

$ mkdir chapter_8_hands_on
$ cd chapter_8_hands_on

创建一个空的Terraform配置文件,命名为main.tf,可以通过Shell命令或使用VS Code创建:

$ touch main.tf

可选地,你可以从本章的GitHub仓库克隆示例项目,仓库地址为:github.com/PacktPublis…。接下来,通过选择 File | Open Folder 打开该目录,定位到目录位置,在VS Code中打开它。

定义Terraform资源

让我们从扩展本章开头“设置本地Terraform环境”部分引入的Terraform示例开始。可以复制现有的main.tf文件,或者直接编辑现有main.tf配置文件的主体。

首先,我们通过在databricks_notebook资源定义中添加第二个数据集来扩展DLT管道定义(以下代码块省略了“定义DLT管道源笔记本”部分的代码以便简洁)。现在,我们将有一个包含两个数据集的数据管道——一个铜层和一个银层。将以下内容更新到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
  )
}

接下来,在我们创建一个新的DLT管道之前,我们需要在Unity Catalog中定义一个位置来存储管道的数据集。将以下catalogschema资源定义添加到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"
}

现在我们有了包含DLT管道定义的源笔记本和一个存储管道数据集的位置,我们可以定义一个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"
}

你会注意到我们已经定义了包含DLT管道定义的笔记本位置、用于管道更新和维护任务的默认集群,以及其他运行时设置,如开发模式、产品版本、渠道等。

接下来,我们希望协调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"
    }
  }
}

最后,我们希望输出已部署资源的工作流URL,以便我们可以从浏览器轻松打开工作流UI。将以下输出定义添加到main.tf文件:

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

部署Terraform项目

在我们开始部署新资源之前,第一步是初始化Terraform项目。通过VS Code命令面板或从Shell提示符执行terraform init命令,初始化项目:

$ terraform init

接下来,通过执行terraform plan命令预览Terraform文件中的更改,查看建议的基础设施更改:

$ terraform plan

总的来说,应该会创建五个新的资源,包括databricks_notebook资源,该资源代表包含DLT管道定义的笔记本、目标Unity Catalog的目录、目标Unity Catalog模式、databricks_pipeline资源,它代表我们的DLT管道,以及databricks_job资源,它代表将触发管道更新的工作流。

在验证了计划后,我们可以将DLT管道部署到Databricks工作区。接下来,执行terraform apply命令,将新的基础设施更改应用到工作区:

$ terraform apply

一旦所有资源更改都已应用,你应该会看到Terraform输出Databricks工作流的URL。

复制并粘贴工作流URL到浏览器窗口,确保该地址指向目标工作区中刚创建的工作流。你会注意到新创建的工作流包含一个任务,用于更新DLT管道。工作流处于暂停状态,如Terraform配置中所示。可选地,你可以点击蓝色的“立即运行”按钮,触发工作流的即时运行。

image.png

虽然将更改部署到目标Databricks工作区非常简单,但撤销这些更改同样也很容易。执行以下命令,以从目标Databricks工作区移除所有资源更改:

$ terraform destroy

通过输入yes来确认这一决定。可能需要几分钟的时间,才能完全撤销所有资源的部署。

正如你所看到的,通过几次键击和点击按钮,使用Databricks Terraform提供程序在Databricks工作区中快速、轻松地进行资源的创建和撤销部署。我们并没有直接指示Terraform如何将资源部署到目标Databricks工作区,而是专注于通过配置指定要进行的更改,让Terraform工具为我们处理复杂的部分。

总结

在本章中,我们介绍了如何使用Databricks Terraform提供程序实现CI/CD流程,以在工作区之间部署数据管道。我们看到,设置本地开发环境以处理Terraform配置文件是多么简单,并且在将Terraform计划应用到目标环境之前,测试这些计划也变得非常容易。我们还从Terraform Registry安装了Databricks Terraform提供程序,并将该提供程序导入到Terraform配置文件中。接下来,我们深入了解了databricks_pipeline资源,该资源由Databricks Terraform提供程序用于将DLT管道部署到目标工作区。我们检查了资源规范中的每个参数,并了解了如何控制DLT管道的运行时配置、计算设置,甚至是管道输出数据集的位置。最后,我们展示了如何通过将Terraform配置文件存储在版本控制系统(如GitHub)中,并使用构建工具(如Azure DevOps Pipelines)自动化部署,轻松地实现自动化。我们以一个实际操作示例作为结尾,展示了如何使用Terraform扩展与流行的代码编辑器VS Code结合,从本地开发环境部署DLT管道。

然而,Terraform并不适用于所有人,对于某些使用场景,它可能过于复杂或难以使用。在下一章中,我们将深入介绍Databricks资产包(DABs),这是一种简单的CI/CD工具,用于打包和部署Databricks代码工件,特别适用于数据和机器学习工作负载。