Databricks Terraformプロバイダー

HashiCorp Terraform は、複数のクラウド プロバイダー間で安全で予測可能なクラウド インフラストラクチャを作成するための一般的なオープンソース ツールです。 Databricks Terraform プロバイダーを使用すると、柔軟で強力なツールを使用して、Databricks ワークスペースと関連するクラウド インフラストラクチャを管理できます。Databricks Terraform プロバイダーの目標は、すべての Databricks REST APIsをサポートし、データ プラットフォームのデプロイと管理の最も複雑な側面の自動化をサポートすることです。 Databricks 顧客は、Databricks Terraform プロバイダーを使用して、クラスターとジョブをデプロイおよび管理し、データ アクセスを構成しています。 Databricks Terraform プロバイダーを使用して Databricks ワークスペースをプロビジョニングし、Google クラウドプラットフォームプロバイダーを使用して、これらのワークスペースに必要な Google クラウド プラットフォーム リソースをプロビジョニングします。

はじめに

このセクションでは、ローカル開発マシンで Terraform と Databricks Terraform プロバイダーを使用するための要件をインストールして構成します。 次に、Terraform認証を構成します。 このセクションに続いて、この記事では、Databricks ノートブック、クラスター、および既存の Databricks ワークスペースのクラスターでノートブックを実行するジョブをプロビジョニングするためにエクスペリメントできる サンプル構成 について説明します。

要件

  1. Terraform CLIが必要です。 Terraform の Web サイトの「 Terraform のダウンロード 」を参照してください。

  2. Terraform プロジェクトが必要です。 ターミナルで、空のディレクトリを作成し、それに切り替えます。 (Terraform構成ファイルの個別のセットは、Terraform プロジェクトと呼ばれる独自のディレクトリに存在する必要があります。 たとえば、 mkdir terraform_demo && cd terraform_demoです。

    mkdir terraform_demo && cd terraform_demo
    

    プロジェクトのTerraform構成をTerraformプロジェクトの1つ以上の構成ファイルに含めます。 構成ファイルの構文の詳細は、Terraform Webサイトの Terraform言語ドキュメント を参照してください。

  3. Terraform プロジェクトに Databricks Terraform プロバイダーの依存関係を追加する必要があります。 Terraformプロジェクトの構成ファイルの1つに次を追加します:

    terraform {
      required_providers {
        databricks = {
          source = "databricks/databricks"
        }
      }
    }
    
  4. Terraformプロジェクトの認証を構成する必要があります。 Databricks Terraform プロバイダーのドキュメントの 「認証 」を参照してください。

サンプル構成

このセクションでは、既存の Databricks ワークスペースで、Databricks ノートブック、クラスター、およびクラスター上でノートブックを実行するジョブをプロビジョニングするために試すことのできるサンプルの構成を提供します。ここでは、前のセクションで説明のある通りに、要件が既に設定され、Terraform プロジェクトが作成され、 Terraform 認証を使用してプロジェクトが構成されていることを前提とします。

  1. Terraformプロジェクトに me.tf という名前のファイルを作成し、次のコードを追加します。 このファイルは、現在のユーザー(あなた)に関する情報を取得します。

    # Retrieve information about the current user.
    data "databricks_current_user" "me" {}
    
  2. 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
    }
    
  3. notebook.auto.tfvarsという名前の別のファイルを作成し、次のコードを追加します。このファイルは、ノートブックのプロパティを指定します。

    notebook_subdirectory = "Terraform"
    notebook_filename     = "notebook-getting-started.py"
    notebook_language     = "PYTHON"
    
  4. notebook-getting-started.pyという名前の別のファイルを作成し、次のコードを追加します。このファイルは、ノートブックの内容を表します。

    display(spark.range(10))
    
  5. 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
    }
    
  6. cluster.auto.tfvarsという名前の別のファイルを作成し、次のコードを追加します。このファイルは、クラスターのプロパティを指定します。

    cluster_name                    = "My Cluster"
    cluster_autotermination_minutes = 60
    cluster_num_workers             = 1
    
  7. 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
    }
    
  8. job.auto.tfvarsという名前の別のファイルを作成し、次のコードを追加します。このファイルは、ジョブのプロパティを指定します。

    job_name = "My Job"
    task_key = "my_task"
    
  9. terraform planを実行します。エラーがある場合は、それらを修正してからコマンドを再実行します。

  10. terraform applyを実行します。

  11. ノートブック、クラスター、ジョブが作成されたことを確認します。 terraform apply コマンドの出力で、 notebook_urlcluster_urljob_urlの URL を探し、その場所に移動します。

  12. ジョブを実行します。:[ジョブ]ページで、[今すぐ実行] をクリックします。ジョブが完了したら、Eメールの受信トレイを確認します。

  13. このサンプルテストを完了したら、 terraform destroyを実行して Databricks ワークスペースからノートブック、クラスター、ジョブを削除します。

    terraform planterraform applyおよびterraform destroyコマンドの詳細は、TerraformドキュメントのTerraform CLIドキュメントを参照してください。

  14. ノートブック、クラスター、およびジョブが削除されたことを確認します:ノートブック、クラスター、[ジョブ] ページを更新すると、それぞれにリソースが見つからないことを示すメッセージが表示されます。

テスティング

Terraform 構成をデプロイする前またはデプロイした後にテストします。 リソースをデプロイする前に、ユニット テストに類似したテストを実行できます。 リソースがデプロイされた後、統合テストに類似したテストを実行することもできます。 Terraform ドキュメントのテストを参照してください。

次のプロセスに従って、この記事のサンプル構成に対して統合テストに類似したテストを実行します。

  1. 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"
      }
    }
    
  2. 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"
      }
    }
    
  3. 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"
      }
    }
    
  4. terraform testを実行します。 Terraform は各リソースを Databricks ワークスペースにデプロイし、関連する各テストを実行してそのテスト結果を報告し、デプロイされたリソースを破棄します。

次のプロセスで、この記事のサンプル構成に対して単体テストと同様のテストを実行します。

  • 前述の各テストの行command = applycommand = planに変更し、 terraform testを実行します。 Terraform は関連する各テストを実行し、そのテスト結果を報告しますが、リソースはデプロイしません。

  • Databricks Terraform プロバイダーをモックします。これにより、リソースをデプロイせずに、また認証資格情報を必要とせずにterraform testを実行できるようになります。 Terraform ドキュメントのMocksを参照してください。 模擬テストを実行する方法の 1 つは、テストに行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"
  }
}

関連リソース