HashiCorp Terraform 是一种常用的开放源工具,可用于跨多个云提供程序创建安全且可预测的云基础结构。 可使用 Databricks Terraform 提供程序通过灵活强大的工具来管理 Azure Databricks 工作区和关联的云基础结构。 Databricks Terraform 提供程序的目标是支持所有 Databricks REST API,从而支持自动化执行部署和管理数据平台中的最复杂部分。 Databricks 客户可使用 Databricks Terraform 提供程序来部署和管理群集和作业以及配置数据访问。 使用 Azure 提供程序预配 Azure Databricks 工作区。
在本部分中,你将在本地开发计算机上安装和配置使用 Terraform 和 Databricks Terraform 提供程序的要求。 然后配置 Terraform 身份验证。 在本部分之后,本文提供了一个示例配置,你可以在现有 Azure Databricks 工作区中使用该配置进行试验,以预配 Azure Databricks 笔记本、群集以及在群集上运行笔记本的作业。
必须具有 Terraform CLI。 请查看 Terraform 网站上的下载 Terraform。
必须具有 Terraform 项目。 在终端中,创建一个空目录,然后切换到该目录。 (每组单独的 Terraform 配置文件必须位于其自己的目录中,该目录称为一个 Terraform 项目。)例如:
mkdir terraform_demo && cd terraform_demo
。export ARM_ENVIRONMENT=china mkdir terraform_demo && cd terraform_demo
在 Terraform 项目中的一个或多个配置文件中包含项目的 Terraform 配置。 有关配置文件语法的信息,请参阅 Terraform 网站上的 Terraform 语言文档。
必须向 Terraform 项目添加 Databricks Terraform 提供程序的依赖项。 将以下内容添加到 Terraform 项目中的某个配置文件:
terraform { required_providers { databricks = { source = "databricks/databricks" } } }
必须为 Terraform 项目配置身份验证。 请参阅 Databricks Terraform 提供程序文档中的身份验证。
本部分提供了一个示例配置,你可以在现有 Azure Databricks 工作区中进行试验,以预配 Azure Databricks 笔记本、群集以及在群集上运行笔记本的作业。 它假定你已经设置了所需内容,以及创建了一个 Terraform 项目并为该项目配置了 Terraform 身份验证,如上一节所述。
在 Terraform 项目中创建一个名为
me.tf
的文件,并添加以下代码。 此文件获取有关当前用户(你)的信息:# Retrieve information about the current user. data "databricks_current_user" "me" {}
创建另一个名为
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 }
创建另一个名为
notebook.auto.tfvars
的文件,并添加以下代码。 此文件指定笔记本的属性。notebook_subdirectory = "Terraform" notebook_filename = "notebook-getting-started.py" notebook_language = "PYTHON"
创建另一个名为
notebook-getting-started.py
的文件,并添加以下代码。 此文件表示笔记本的内容。display(spark.range(10))
创建另一个名为
cluster.tf
的文件,并添加以下代码。 此文件表示群集。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 }
创建另一个名为
cluster.auto.tfvars
的文件,并添加以下代码。 此文件指定群集的属性。cluster_name = "My Cluster" cluster_autotermination_minutes = 60 cluster_num_workers = 1
创建另一个名为
job.tf
的文件,并添加以下代码。 此文件表示在群集上运行笔记本的作业。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 }
创建另一个名为
job.auto.tfvars
的文件,并添加以下代码。 此文件指定作业的属性。job_name = "My Job" task_key = "my_task"
运行
terraform plan
。 如果报告了任何错误,请修复它们,然后再次运行该命令。运行
terraform apply
。验证笔记本、群集和作业是否已创建:在
terraform apply
命令的输出中,找到notebook_url
、cluster_url
和job_url
的 URL 并转到它们。运行作业:在“作业”页面上,单击“立即运行”。 在作业完成后,检查电子邮件收件箱。
完成此示例后,请运行
terraform destroy
,从 Azure Databricks 工作区删除笔记本、群集和作业。注意
有关命令
terraform plan
、terraform apply
和terraform destroy
的详细信息,请参阅 Terraform 文档中的 Terraform CLI 文档。验证笔记本、群集和作业是否已删除:刷新笔记本、群集和“作业”页面,查看是否显示“找不到资源”消息。
在部署 Terraform 配置之前或之后对其进行测试。 在部署资源之前,你可以运行类似于单元测试的测试。 还可以在部署资源后运行类似于集成测试的测试。 请参阅 Terraform 文档中的测试。
按照以下过程针对本文的示例配置运行类似于集成测试的测试:
创建一个名为
cluster.tftest.hcl
的文件,并添加以下代码。 此文件测试所部署的群集是否具有预期的群集名称。# Filename: cluster.tftest.hcl run "cluster_name_test" { command = apply assert { condition = databricks_cluster.this.cluster_name == var.cluster_name error_message = "Cluster name did not match expected name" } }
创建一个名为
job.tftest.hcl
的文件,并添加以下代码。 此文件测试所部署的作业是否具有预期的作业名称。run "job_name_test" { command = apply assert { condition = databricks_job.this.name == var.job_name error_message = "Job name did not match expected name" } }
创建一个名为
notebook.tftest.hcl
的文件,并添加以下代码。 此文件测试所部署的笔记本是否具有预期的工作区路径。run "notebook_path_test" { command = apply assert { condition = databricks_notebook.this.path == "${data.databricks_current_user.me.home}/${var.notebook_subdirectory}/${var.notebook_filename}" error_message = "Notebook path did not match expected path" } }
运行
terraform test
。 Terraform 将每个资源部署到 Azure Databricks 工作区,运行每个相关测试并报告其测试结果,然后拆除所部署的资源。
按照以下过程针对本文的示例配置运行类似于单元测试的测试:
- 将上述每个测试中的行
command = apply
更改为command = plan
,然后运行terraform test
。 Terraform 运行每个相关的测试并报告其测试结果,但不部署任何资源。 - 模拟 Databricks Terraform 提供程序,这可以在不部署资源的情况下运行
terraform test
,也不会要求提供任何身份验证凭据。 请参阅 Terraform 文档中的模拟。 若要运行模拟测试,一种方法是将行mock_provider "databricks" {}
添加到测试,并移除行command = apply
或command = plan
,例如:
# Filename: cluster.tftest.hcl
mock_provider "databricks" {}
run "cluster_mock_name_test" {
assert {
condition = databricks_cluster.this.cluster_name == var.cluster_name
error_message = "Cluster name did not match expected name"
}
}
# Filename: job.tftest.hcl
mock_provider "databricks" {}
run "job_mock_name_test" {
assert {
condition = databricks_job.this.name == var.job_name
error_message = "Job name did not match expected name"
}
}
# Filename: notebook.tftest.hcl
mock_provider "databricks" {}
run "notebook_mock_path_test" {
assert {
condition = databricks_notebook.this.path == "${data.databricks_current_user.me.home}/${var.notebook_subdirectory}/${var.notebook_filename}"
error_message = "Notebook path did not match expected path"
}
}
- Terraform 注册表网站上的 Databricks 提供程序文档
- Terraform 网站上的 Terraform 文档
- GitHub 中的 Databricks Terraform examples 存储库