次の方法で共有


Pulumi Databricks リソース プロバイダー

注意

この記事では、Databricks によって提供もサポートもされていない Pulumi について説明します。 プロバイダーに問い合わせるには、Pulumi のサポートをご覧ください。

この記事では、Python と Pulumi を使用する方法について説明します。後者は、使い慣れたプログラミング言語、ツール、エンジニアリング プラクティスを使用して Azure Databricks リソースを作成、デプロイ、管理できる、サードパーティによるコードとしてのインフラストラクチャ (IaC) プラットフォームです。 この記事では、Python と Pulumi Databricks リソース プロバイダーの使用方法について説明しますが、Pulumi では Azure Databricks 用の Python に加えて TypeScript、JavaScript、Go、C# などの他の言語もサポートされています。

Pulumi Databricks リソース プロバイダーは、Databricks Terraform プロバイダーに基づいています。 詳細については、Terraform Cloud のページを参照してください。

必要条件

  • Pulumi アカウント。 Pulumi アカウントをまだ持っていない場合は、Pulumi にサインアップしてください。 個人向けの Pulumi は無料です。また、チーム向けの無料レベルが用意されています。

  • Python 3.6 以上。 Python がインストールされているかどうかを確認するには、ターミナルから、または PowerShell を使用してコマンド python --version を実行します。 Python をまだインストールしていない場合はインストールします。

    注意

    Python の一部のインストールでは、python ではなく python3 を使用する必要があります。 その場合は、この記事全体を通して、pythonpython3 に置き換えてください。

  • Azure Databricks ワークスペース単位の URL (例: https://adb-1234567890123456.7.azuredatabricks.net)

  • Azure Databricks のアクセス資格情報。 Pulumi Databricks プロジェクトは、次の Azure Databricks 認証の種類をサポートしています。

次の手順では、Python を使用して Pulumi Databricks プロジェクトを作成する方法を示します。 それの代わりに、完全にクラウド プロバイダー優先の観点からのチュートリアルについては、Pulumi ドキュメントの「Azure の概要」を参照してください。 または、プログラミング言語優先の観点からのチュートリアルについては、Pulumi ドキュメントの「Python」、「Node.js (JavaScript、TypeScript)」、「Go」、「.NET (C#、VB、F#)」を参照してください。

手順 1: Pulumi プロジェクトを作成する

この手順では、Pulumi プロジェクトに必要なディレクトリ構造をローカル開発マシン上に設定します。 次に、このディレクトリ構造内に Pulumi プロジェクトを作成します。

  1. ターミナルまたは PowerShell で空のディレクトリを作成し、次のようにしてそれに切り替えます。

    Unix、Linux、macOS

    mkdir pulumi-demo
    cd pulumi-demo
    

    Windows

    md pulumi-demo
    cd pulumi-demo
    
  2. オペレーティング システムに応じた次のコマンドを実行して、Pulumi をインストールします。

    Unix、Linux

    Unix または Linux に Pulumi をインストールするには、curl を使用します。

    curl -fsSL https://get.pulumi.com | sh
    

    MacOS

    macOS に Pulumi をインストールするには、Homebrew を使用します。

    brew install pulumi/tap/pulumi
    

    Windows

    Windows に Pulumi をインストールするには、Chocolatey パッケージ マネージャーで、管理者特権のアクセス許可を持つ PowerShell を使用します。

    choco install pulumi
    

    Pulumi インストールの代替オプションについては、Pulumi ドキュメントの「ダウンロードとインストール」を参照してください。

  3. 次のコマンドを実行して、基本的な Python Pulumi プロジェクトを作成します。

    pulumi new python
    

    ヒント

    オンラインで Pulumi アカウントから Pulumi プロジェクトを作成することもできます ([プロジェクト] > [プロジェクトの作成])。 ただし、Azure Databricks 用のプロジェクト テンプレートはありません。

  4. メッセージが表示されたら、Enter キーを押し、Web ブラウザーを使用して、まだサインインしていない場合は Pulumi アカウントにオンラインでサインインします。 サインインしたら、ターミナルまたは PowerShell に戻ります。

  5. プロジェクト名の入力を求められたら、Enter キーを押して既定のプロジェクト名である pulumi-demo をそのまま使用します。

  6. プロジェクトの説明の入力を求められたら、「A demo Python Pulumi Databricks project」と入力して Enter キーを押します。

  7. スタック名の入力を求められたら、Enter キーを押して既定のスタック名である dev をそのまま使用します。 Pulumi で次のファイルとサブディレクトリが pulumi-demo ディレクトリに作成されます。

    • Pulumi.yaml は、Pulumi プロジェクトの設定の一覧です。
    • __main__.py には、Pulumi プロジェクト用に記述する Python コードが含まれます。
    • requirements.txt は、プロジェクトに対して Pulumi によってインストールされる、サポート対象 Python コード パッケージの一覧です。
    • .gitignore は、このプロジェクトをリモート Git リポジトリにプッシュする場合に Git で無視されるファイルとディレクトリの一覧です。
    • venv サブディレクトリには、Pulumi でプロジェクト用に使用されるサポート対象の Python 仮想環境コードが含まれています。
  8. 次のコマンドを実行して、プロジェクトの dev スタックの最初のデプロイを実行します。

    pulumi up
    
  9. この更新の実行を求められたら、上方向キーを押して [yes] (はい) に移動し、Enter キーを押します。

  10. 表示された [View Live] (ライブ表示) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けると、オンラインで Pulumi アカウントに移動します。 pulumi-demo プロジェクトについて、dev スタックのアクティビティ詳細が表示されます。 スタックにはリソースがまだないため、現時点では表示されるものは多くありません。 次の手順でこれらのリソースを作成します。

手順 2: Databricks リソースを作成する

この手順では、Pulumi Databricks リソース プロバイダーを使用して、既存の Azure Databricks ワークスペースにノートブックとそのノートブックを実行するジョブを作成します。

  1. Pulumi で生成された __main.py__ ファイルで、好みのテキスト エディターまたは統合開発環境 (IDE) を使って次のコードを入力します。 このコードで、Pulumi Databricks の Notebook および Job リソースとその設定を宣言します。

    """A Python Pulumi program"""
    
    import pulumi
    from pulumi_databricks import *
    from base64 import b64encode
    
    # Get the authenticated user's workspace home directory path and email address.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/getcurrentuser
    user_home_path     = get_current_user().home
    user_email_address = get_current_user().user_name
    
    # Define the name prefix to prepend to the resource names that are created
    # for the Notebook and Job resources. To do this, you can use a Pulumi
    # configuration value instead of hard-coding the name prefix in this file.
    #
    # To set a Pulumi configuration value, run the following command, which sets
    # a "resource-prefix" configuration value to "pulumi-demo" in the
    # associated "Pulumi.<stack-name>.yaml" configuration file:
    #
    # pulumi config set resource-prefix "pulumi-demo"
    #
    # For more information about defining and retrieving hard-coded values, see
    # https://www.pulumi.com/docs/intro/concepts/config
    config = pulumi.config.Config()
    resource_prefix = config.require('resource-prefix')
    
    # Define cluster resource settings.
    node_type = config.require('node-type')
    
    # Create a Notebook resource.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/notebook
    # This example adds a single cell to the notebook, which is constructed from
    # a single base64-encoded string. In practice, you would replace this:
    #
    # language       = "PYTHON",
    # content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    #
    # With this:
    #
    # source         = "path/to/local/my-notebook.py"
    #
    # To provide more notebook content easier and faster. Also, the notebook's language
    # is automatically detected. If you specify a notebook path, be sure that it does
    # not end in .ipynb, as Pulumi relies on the workspace import API, which doesn't
    # rely on any specific extensions such as .ipynb in the notebook path.
    notebook = Notebook(
      resource_name  = f"{resource_prefix}-notebook",
      path           = f"{user_home_path}/Pulumi/{resource_prefix}-notebook.py",
      language       = 'PYTHON',
      content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    )
    
    # Export the URL of the Notebook, so that you can easily browse to it later.
    # See https://www.pulumi.com/docs/intro/concepts/stack/#outputs
    pulumi.export('Notebook URL', notebook.url)
    
    # Create a Job resource.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/job
    # This job uses the most recent Databricks Runtime long-term support (LTS)
    # runtime programmatic version ID at the time this article was first published,
    # which is 14.3.x-scala2.12. You can replace this with a later version.
    job = Job(
      resource_name = f"{resource_prefix}-job",
      name = f"{resource_prefix}-job",
      tasks = [
        JobTaskArgs(
          task_key = f"{resource_prefix}-task",
          new_cluster   = JobNewClusterArgs(
            num_workers   = 1,
            spark_version = "14.3.x-scala2.12",
            node_type_id  = node_type
          ),
          notebook_task = JobNotebookTaskArgs(
            notebook_path = f"{user_home_path}/Pulumi/{resource_prefix}-notebook.py"
          )
        )
      ],
      email_notifications = JobEmailNotificationsArgs(
        on_successes = [ user_email_address ],
        on_failures  = [ user_email_address ]
      )
    )
    
    # Export the URL of the Job, so that you can easily browse to it later.
    # See https://www.pulumi.com/docs/intro/concepts/stack/#outputs
    pulumi.export('Job URL', job.url)
    
  2. 次のコマンドを実行して、resource-prefix という名前の構成値を定義し、それをハードコーディングされた値 pulumi-demo に設定します。 この構成値が Pulumi で使用されて、ノートブックとジョブに名前が付けられます。

    pulumi config set resource-prefix "pulumi-demo"
    

    Pulumi で、__main__.py ファイルと同じディレクトリに Pulumi.dev.yaml という名前のファイルが作成され、この YAML ファイルに次のコードが追加されます。

    config:
      pulumi-demo:resource_prefix: pulumi-demo
    

    構成値を使用すると、コードのモジュール性と再利用性が高まります。 これで、他のユーザーがこの __main__.py ファイルを再利用し、__main__.py ファイルの内容を変更することなく resource_prefix 変数に別の値を定義できるようになりました。

  3. 次のコマンドを実行して、node-type という名前の構成値を定義し、それを次のようにハードコーディングされた値に設定します。 この構成値が Pulumi で使用され、ジョブを実行するクラスターの種類が決定されます。

    pulumi config set node-type "Standard_D3_v2"
    

    この時点で、Pulumi.dev.yaml ファイルの内容は次のようになります。

    config:
      pulumi-demo:node-type: Standard_D3_v2
      pulumi-demo:resource-prefix: pulumi-demo
    
  4. Azure Databricks ワークスペースで Pulumi の認証ができるようにするには、関連コマンドを実行して、Azure Databricks 固有の構成値を定義します。 たとえば、Azure Databricks 個人用アクセス トークン認証の場合は、次のコマンドを実行します。 これらのコマンドでは、次のようにします。

    • <workspace-instance-url>ワークスペースごとの URL に置き換えます (例: https://adb-1234567890123456.7.azuredatabricks.net)。

    • <access-token> は、アクセス トークンの値に置き換えます。 --secret オプションを必ず指定してください。 これにより、セキュリティのベスト プラクティスとしてアクセス トークンを暗号化することを Pulumi に指示します。

      注意

      既定では、Pulumi による値の暗号化には、Pulumi Service によって管理されるスタックごとの暗号化キーと、値ごとの salt が使用されます。 代替の暗号化プロバイダーを使用するには、Pulumi ドキュメントの「シークレット暗号化の構成」を参照してください。

    pulumi config set databricks:host "<workspace-instance-url>"
    pulumi config set databricks:token "<access-token>" --secret
    

    この時点で、Pulumi.dev.yaml ファイルの内容は次のようになります。

    config:
      databricks:host: <your-workspace-instance-url>
      databricks:token:
        secure: <an-encrypted-version-of-your-access-token>
      pulumi-demo:node-type: Standard_D3_v2
      pulumi-demo:resource_prefix: pulumi-demo
    

    別の Azure Databricks 認証の種類を使うには、「要件」を参照してください。 GitHub の Pulumi Databricks リポジトリの「構成」も参照してください。

手順 3: リソースをデプロイする

この手順では、Pulumi Python プロジェクト テンプレート実行の一環として Pulumi によってプロジェクトに提供される、Python 仮想環境をアクティブにします。 この仮想環境は、正しいバージョンの Python、Pulumi、Pulumi Databricks リソース プロバイダーを一緒に使用するのに役立ちます。 用可能な Python 仮想環境フレームワークはいくつかあります。venvvirtualenvpipenv などです。 この記事と Pulumi Python プロジェクト テンプレートでは.venv を使用しています。 venv は既に Python に組み込まれています。 詳細については、「Creating Virtual Environments (仮想環境を作成する)」を参照してください。

  1. オペレーティング システムとシェルの種類に応じた次のコマンドを pulumi-demo ディレクトリから実行し、Python 仮想環境をアクティブ化します。

    プラットフォーム シェル 仮想環境をアクティブ化するコマンド
    Unix、Linux、macOS bash/zsh source venv/bin/activate
    fish source venv/bin/activate.fish
    csh/tcsh source venv/bin/activate.csh
    PowerShell Core venv/bin/Activate.ps1
    Windows cmd.exe venv\Scripts\activate.bat
    PowerShell venv\Scripts\Activate.ps1
  2. 次のコマンドを実行して、Python パッケージ インデックス (PyPI) から仮想環境に Pulumi Databricks リソース プロバイダーをインストールします。

    pip install pulumi-databricks
    

    注意

    pip の一部のインストールでは、pip ではなく pip3 を使用する必要があります。 その場合は、この記事全体を通して、pippip3 に置き換えてください。

  3. 次のコマンドを実行して、Pulumi によって作成されるリソースをプレビューします。

    pulumi preview
    

    エラーが報告された場合は、修正してからコマンドを再実行します。

    Pulumi アカウントで Pulumi によって実行される内容の詳細なレポートをオンラインで表示するには、表示される [View Live] (ライブ表示) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。

  4. 次のコマンドを実行し、リソースを作成して Azure Databricks ワークスペースにデプロイします。

    pulumi up
    
  5. この更新の実行を求められたら、上方向キーを押して [yes] (はい) に移動し、Enter キーを押します。 エラーが報告された場合は、修正してからコマンドを再実行します。

  6. Pulumi アカウントで Pulumi によって実行された内容の詳細なレポートをオンラインで表示するには、表示される [View Live] (ライブ表示) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。

手順 4: リソースを操作する

この手順では、指定したノートブックを実行するジョブを Azure Databricks ワークスペースで実行します。

  1. ワークスペースでジョブによって実行されるノートブックを表示するには、表示される [Notebook URL] (ノートブック URL) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。
  2. ワークスペースでノートブックを実行するジョブを表示するには、表示される [Job URL] (ジョブ URL) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。
  3. ジョブを実行するには、ジョブ ページの [今すぐ実行] ボタンをクリックします。
  4. ジョブの実行が完了したら、ジョブ実行の結果を表示するには、ジョブ ページの [完了した実行 (過去 60 日間)] の一覧で、[開始時刻] 列の最新の時刻エントリをクリックします。 [出力] ペインには、ノートブックのコードを実行した結果が表示され、1 から 10 までの数値が出力されます。

(省略可能) 手順 5: リソースに変更を加える

省略可能なこの手順では、ノートブックのコードを変更し、変更したノートブックを再デプロイしてから、ジョブを使用して、変更したノートブックを再実行します。

ノートブックを変更しない場合は、「手順 6: クリーンアップする」に進んでください。

  1. __main.py__ ファイルに戻り、次のコード行を変更します。

    content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    

    このようにしたら、ファイルを保存します。

      content_base64 = b64encode(b'''
    data = [
             { "Category": 'A', "ID": 1, "Value": 121.44 },
             { "Category": 'B', "ID": 2, "Value": 300.01 },
             { "Category": 'C', "ID": 3, "Value": 10.99 },
             { "Category": 'E', "ID": 4, "Value": 33.87}
           ]
    
    df = spark.createDataFrame(data)
    
    display(df)
    ''').decode("UTF-8")
    

    この変更により、数値 1 から 10 ではなく、指定した DataFrame の内容を出力するようにノートブックに指示します。

    Note

    data で始まり ''').decode("UTF-8") で終わるコード行が、コード エディターの端に揃っていることを確認します。 そうでないと、Pulumi によってノートブックに追加の空白が挿入され、それが原因で新しい Python コードの実行が失敗する可能性があります。

  2. 必要に応じて、次のコマンドを実行して、Pulumi によって変更されるリソースをプレビューします。

    pulumi preview
    

    エラーが報告された場合は、修正してからコマンドを再実行します。

    Pulumi アカウントで Pulumi によって実行される内容の詳細なレポートをオンラインで表示するには、表示される [View Live] (ライブ表示) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。

  3. 次のコマンドを実行して、リソースの変更を Azure Databricks ワークスペースにデプロイします。

    pulumi up
    
  4. この更新の実行を求められたら、上方向キーを押して [yes] (はい) に移動し、Enter キーを押します。 エラーが報告された場合は、修正してからコマンドを再実行します。

  5. Pulumi アカウントで Pulumi によって実行された内容の詳細なレポートをオンラインで表示するには、表示される [View Live] (ライブ表示) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。

  6. ワークスペースで変更されたノートブックを表示するには、表示される [Notebook URL] (ノートブック URL) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。

  7. 変更されたノートブックでジョブを再実行するには、表示される [Job URL] (ジョブ URL) のリンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。 次に、ジョブ ページの [今すぐ実行] ボタンをクリックします。

  8. ジョブの実行が完了したら、ジョブ実行の結果を表示するには、ジョブ ページの [完了した実行 (過去 60 日間)] の一覧で、[開始時刻] 列の最新の時刻エントリをクリックします。 [出力] ペインには、ノートブックのコードを実行した結果が表示され、指定した DataFrame の内容が出力されます。

手順 6: クリーンアップする

この手順では、Pulumi に指示をして、Azure Databricks ワークスペースからノートブックとジョブを削除し、Pulumi アカウントから pulumi-demo プロジェクトとその dev スタックをオンラインで削除します。

  1. 次のコマンドを実行して、Azure Databricks ワークスペースからリソースを削除します。

    pulumi destroy
    
  2. この削除の実行を求められたら、上方向キーを押して [yes] (はい) に移動し、Enter キーを押します。

  3. 次のコマンドを実行して、Pulumi の pulumi-demo プロジェクトとその dev スタックをオンラインの Pulumi アカウントから削除します。

    pulumi stack rm dev
    
  4. この削除の実行を求められたら、「dev」と入力し、Enter キーを押します。

  5. Python 仮想環境 venv を非アクティブ化するには、次のコマンドを実行します。

    deactivate
    

テスト

Pulumi プロジェクトをデプロイする前にテストできます。 Pulumi ドキュメントの Pulumi プログラムのテストを参照してください。

Python ベースの Pulumi プロジェクトの単体テストでは、Python テスト フレームワーク unittest と、Pulumi パッケージの pulumi.runtime 名前空間を使用して単体テストを記述して実行できます。 シミュレートされたリソースに対してテストを実行するには、Pulumi (および Azure Databricks) の呼び出しをモックに置き換えます。 Pulumi ドキュメントの Pulumi プログラムの単体テストを参照してください。

infra.py という名前の次のファイル例は、この記事の main.py ファイルで宣言されているノートブックとジョブの実装をモックします。 この例の単体テストでは、ノートブックの Base64 でエンコードされたコンテンツ、ジョブの名前、成功したジョブ実行のメール受信者が、すべて期待値を返すかどうかを確認します。 そのため、ここでは値の例を使用して、関連するプロパティのみをモックします。 また、必要なリソース プロパティ値は、単体テストで使用する予定がない場合でも、常に指定する必要があります。 この例では、これらの必須値はランダムな my-mock- 値に設定され、それらの値はテストされません。

# infra.py

from pulumi_databricks import (
  Notebook,
  Job,
  JobEmailNotificationsArgs
)

notebook = Notebook(
  resource_name  = 'my-mock-notebook-resource-name',
  path           = 'my-mock-notebook-path',
  content_base64 = 'ZGlzcGxheShzcGFyay5yYW5nZSgxMCkp'
)

job = Job(
  resource_name = 'my-mock-job-resource-name',
  name          = 'pulumi-demo-job',
  email_notifications = JobEmailNotificationsArgs(
    on_successes = [ 'someone@example.com' ]
  )
)

次のファイル例 test_main.py では、関連するプロパティが期待値を返すかどうかをテストします。

# test_main.py

import pulumi
from pulumi_databricks import *
import unittest
import infra

# Set up mocking.
class MyMocks(pulumi.runtime.Mocks):
  def new_resource(self, type_, name, inputs, provider, id_):
    return [name + '_id', inputs]

  def call(self, token, args, provider):
    return {}

pulumi.runtime.set_mocks(MyMocks())

class TestNotebookAndJob(unittest.TestCase):
  @pulumi.runtime.test
  def test_notebook(self):
    def check_notebook_content_base64(args):
      content_base64 = args
      # Does the notebook's Base64-encoded content match the expected value?
      self.assertIn('ZGlzcGxheShzcGFyay5yYW5nZSgxMCkp', content_base64)

    # Pass the mocked notebook's content_base64 property value to the test.
    return pulumi.Output.all(infra.notebook.content_base64).apply(check_notebook_content_base64)

  @pulumi.runtime.test
  def test_job(self):
    def check_job_name_and_email_onsuccesses(args):
      name, email_notifications = args
      # Does the job's name match the expected value?
      self.assertIn('pulumi-demo-job', name)
      # Does the email address for successful job runs match the expected value?
      self.assertIn('someone@example.com', email_notifications['on_successes'])

    # Pass into the test the mocked job's property values for the job's name
    # and the job's email address for successful runs.
    return pulumi.Output.all(
      infra.job.name,
      infra.job.email_notifications
    ).apply(check_job_name_and_email_onsuccesses)

これらのテストを実行し、テスト結果を表示するには、Pulumi プロジェクトのルート ディレクトリから次のコマンドを実行します。

python -m unittest

実行できるその他の種類のテストについては、Pulumi ドキュメントの次の記事を参照してください。

その他のリソース