Pulumi Databricks リソース プロバイダー
注
この記事では、Databricks によって提供もサポートもされていない Pulumi について説明します。 プロバイダーに連絡するには、「 Pulumi サポート」を参照してください。
この記事では、使い慣れたプログラミング言語、ツール、エンジニアリング手法を使用して Databricks リソースを作成、配置、管理できるサードパーティのInfrastructure-as-Code (IaC) プラットフォームである Python と Pulumi を使用する方法について説明します。 この記事では Python と Pulumi Databricks リソース プロバイダーの使用方法について説明しますが、 Pulumi は Python for Databricks に加えて、TypeScript、JavaScript、Go、C# などの他の言語をサポートしています。
Pulumi Databricks リソース プロバイダーは、 Databricks Terraform プロバイダーに基づいています。 詳細については、「 Terraform クラウド」を参照してください。
要件
プルミのアカウント。 Pulumiアカウントをまだお持ちでない場合は、Pulumiにサインアップしてください。Pulumiは個人は無料で、チームには無料枠を提供しています。
Python 3.6 以上。 Python がインストールされているかどうかを確認するには、ターミナルまたは PowerShell を使用してコマンド
python --version
を実行します。 Python をまだインストールしていない場合は、インストールします。注
Python のインストールによっては、
python
の代わりにpython3
を使用する必要がある場合があります。その場合は、この記事全体でpython3
python
に置き換えてください。Databricks ワークスペース インスタンスの URL(
https://1234567890123456.7.gcp.databricks.com
など)。Databricks のアクセス資格情報。 Pulumi Databricks プロジェクトでは、次の Databricks 認証の種類がサポートされています。
Databricks personal アクセストークン認証 (
databricks:authType pat
)
GitHub の Pulumi Databricks リポジトリの 「構成 」を参照してください。
次のステップは、Python を使用して Pulumi Databricks プロジェクトを作成する方法を示しています。 純粋なクラウド プロバイダー ファーストの観点からのチュートリアルについては、Pulumi ドキュメントの「 Google Cloud の使用を開始する 」を参照してください。 代わりに、プログラミング言語優先の観点からのチュートリアルについては、Pulumi ドキュメントの「Python、Node.js (JavaScript、TypeScript)、Go、および .NET (C#、VB、F#)」を参照してください。
ステップ 1: Pulumi プロジェクトを作成する
このステップでは、ローカル開発マシンで、Pulumi プロジェクトに必要なディレクトリ構造を設定します。 次に、このディレクトリ構造内に Pulumi プロジェクトを作成します。
ターミナルまたはPowerShellから、空のディレクトリを作成し、次のように切り替えます。
mkdir pulumi-demo cd pulumi-demo
md pulumi-demo cd pulumi-demo
オペレーティングシステムに応じて、次のコマンドを実行してPulumiをインストールします。
Unix または Linux に Pulumi をインストールするには、 curl を使用します。
curl -fsSL https://get.pulumi.com | sh
自作を使用してmacOSにプルミをインストールします。
brew install pulumi/tap/pulumi
Chocolatey パッケージ マネージャーを使用して昇格されたアクセス許可を持つ PowerShell を使用して、Windows に Pulumi をインストールします。
choco install pulumi
代替の Pulumi インストール オプションについては、Pulumi ドキュメントの「 ダウンロードとインストール 」を参照してください。
次のコマンドを実行して、基本的な Python Pulumi プロジェクトを作成します。
pulumi new python
ヒント
PulumiアカウントからオンラインでPulumiプロジェクトを作成することもできます(プロジェクト>プロジェクトの作成)。ただし、Databricks のプロジェクト テンプレートはありません。
プロンプトが表示されたら、 Enter キーを押してから、Web ブラウザーを使用して Pulumi アカウントにオンラインでサインインします (まだサインインしていない場合)。 サインインしたら、ターミナルまたは PowerShell に戻ります。
プロジェクト名の入力を求めるプロンプトが出されたら、Enter キーを押してデフォルトのプロジェクト名
pulumi-demo
を受け入れ ます。プロジェクトの説明の入力を求めるプロンプトが出されたら、
A demo Python Pulumi Databricks project
を入力して Enter キーを押します。スタック名の入力を求められたら、Enter キーを押してデフォルトのスタック名
dev
を受け入れ ます。Pulumi は、pulumi-demo
ディレクトリに次のファイルとサブディレクトリを作成します。Pulumi.yaml
これは、Pulumi プロジェクトの設定のリストです。__main__.py
これには、Pulumi プロジェクト用に記述した Python コードが含まれています。requirements.txt
これは、Pulumi がプロジェクト用にインストールするサポートする Python コード パッケージのリストです。.gitignore
これは、このプロジェクトをリモート Git リポジトリにプッシュする場合に Git が無視するファイルとディレクトリのリストです。venv
サブディレクトリには、Pulumi がプロジェクトに使用するサポート Python 仮想環境コードが含まれています。
次のコマンドを実行して、プロジェクトの
dev
スタックの初期デプロイを実行します。pulumi up
この更新を実行するように求められたら、上方向キーを押して [はい ] に移動し、 Enter キーを押します。
表示される [ライブを表示 ] リンクをコピーして Web ブラウザーのアドレス バーに貼り付けると、 オンラインで Pulumi アカウントに移動します。
pulumi-demo
プロジェクトのdev
スタックのアクティビティの詳細が表示されます。スタックにはまだリソースがないため、現在見るものはあまりありません。 これらのリソースは次のステップで作成します。
ステップ 2: Databricks リソースを作成する
このステップでは、Pulumi Databricks リソース プロバイダーを使用して、既存の Databricks ワークスペースにノートブックと、そのノートブックを実行するジョブを作成します。
Pulumi が生成した
__main.py__
ファイルで、任意のテキスト エディターまたは統合開発環境 (IDE) を使用して次のコードを入力します。 このコードでは、Pulumi Databricks ノートブック と ジョブ のリソースとその設定を宣言します。"""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)
次のコマンドを実行して、
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
変数に別の値を定義できます。node-type
という名前の構成値を定義し、次のコマンドを実行して、次のハードコーディングされた値に設定します。Pulumi は、この構成値を使用して、ジョブが実行されるクラスターのタイプを判別します。pulumi config set node-type "n1-standard-4"
Pulumi.dev.yaml
ファイルの内容は次のようになります。config: pulumi-demo:node-type: n1-standard-4 pulumi-demo:resource-prefix: pulumi-demo
Pulumi が Databricks ワークスペースで認証できるようにするには、関連するコマンドを実行して Databricks 固有の構成値を定義します。 たとえば、Databricks 個人用アクセストークン認証の場合は、次のコマンドを実行します。 これらのコマンドでは、次のようになります。
<workspace-instance-url>
を ワークスペース インスタンスの URL(https://1234567890123456.7.gcp.databricks.com
など) に置き換えます。<access-token>
をアクセストークンの値に置き換えます。必ず--secret
オプションを指定してください。 これにより、セキュリティのベストプラクティスとしてアクセストークンを暗号化するようにPulumiに指示されます。注
デフォルトにより、Pulumi は Pulumi サービスによって管理されるスタックごとの暗号化キーと値ごとのソルトを使用して値を暗号化します。 別の暗号化プロバイダーを使用するには、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: n1-standard-4 pulumi-demo:resource_prefix: pulumi-demo
別の Databricks 認証の種類を使用するには、「 要件」を参照してください。 GitHub の Pulumi Databricks リポジトリの 「構成 」も参照してください。
ステップ 3: リソースをデプロイする
このステップでは、Pulumi Python プロジェクト テンプレートの実行の一環として、Pulumi がプロジェクトに提供する Python 仮想環境 をアクティブ化します。 この仮想環境は、正しいバージョンの Python、Pulumi、および Pulumi Databricks リソース プロバイダーを一緒に使用していることを確認するのに役立ちます。 venv、virtualenv、 pipenv など、いくつかの Python 仮想環境フレームワークが利用可能です。この記事と Pulumi Python プロジェクト テンプレートでは、 venv
を使用します。 venv
はすでに Python に含まれています。 詳細については、「 仮想環境の作成」を参照してください。
オペレーティングシステムとシェルタイプに応じて、
pulumi-demo
ディレクトリから次のコマンドを実行して、Python仮想環境をアクティブ化します。プラットホーム
シェル
仮想環境をアクティブにするコマンド
Unix, Linux, macOS
バッシュ/ZSH
source venv/bin/activate
魚
source venv/bin/activate.fish
csh/tcsh
source venv/bin/activate.csh
PowerShell Core
venv/bin/Activate.ps1
Windows
うん.exe
venv\Scripts\activate.bat
PowerShell
venv\Scripts\Activate.ps1
次のコマンドを実行して、 Pulumi Databricks リソース プロバイダー を Python パッケージ インデックス (PyPI) から仮想環境にインストールします。
pip install pulumi-databricks
注
pip
のインストールによっては、pip
の代わりにpip3
を使用する必要がある場合があります。その場合は、この記事全体でpip3
pip
に置き換えてください。Pulumi が作成するリソースをプレビューするには、次のコマンドを実行します。
pulumi preview
エラーが報告された場合は、それらを修正してからコマンドを再実行します。
PulumiアカウントのPulumiの動作に関する詳細なレポートをオンラインで表示するには、表示される[ ライブを表示 ]リンクをコピーして、Webブラウザーのアドレスバーに貼り付けます。
次のコマンドを実行して、リソースを作成して Databricks ワークスペースにデプロイします。
pulumi up
この更新を実行するように求められたら、上方向キーを押して [はい ] に移動し、 Enter キーを押します。 エラーが報告された場合は、それらを修正してからコマンドを再実行します。
PulumiアカウントのPulumiが行ったことの詳細なレポートをオンラインで表示するには、表示される[ ライブを表示 ]リンクをコピーして、Webブラウザのアドレスバーに貼り付けます。
ステップ 4: リソースを操作する
このステップでは、指定したノートブックを実行する Databricks ワークスペースでジョブを実行します。
ジョブがワークスペースで実行されるノートブックを表示するには、表示される [ノートブック URL ] リンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。
ワークスペースでノートブックを実行するジョブを表示するには、表示される [ ジョブ URL ] リンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。
ジョブを実行するには、ジョブ ページの [ 今すぐ実行 ] ボタンをクリックします。
ジョブの実行が完了したら、ジョブの実行結果を表示するには、ジョブ ページの [完了した実行 (過去 60 日間)] ボックスの一覧で、[開始時刻] 列の最新の 時刻 エントリをクリックします。 [ 出力 ] ウィンドウには、ノートブックのコードを実行した結果が表示され、1 から 10 までの数字が出力されます。
(オプション)ステップ 5: リソースに変更を加える
このオプションの手順では、ノートブックのコードを変更し、変更されたノートブックを再デプロイしてから、ジョブを使用して変更されたノートブックを再実行します。
ノートブックに変更を加えない場合は、「 ステップ 6: クリーンアップ」に進みます。
__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 の内容を印刷するように指示されます。
注
data
で始まり''').decode("UTF-8")
で終わるコード行が、コード エディターの端に揃っていることを確認します。そうしないと、Pulumi はノートブックに追加の空白を挿入し、新しい Python コードの実行が失敗する可能性があります。必要に応じて、次のコマンドを実行して、Pulumi が変更するリソースをプレビューします。
pulumi preview
エラーが報告された場合は、それらを修正してからコマンドを再実行します。
PulumiアカウントのPulumiの動作に関する詳細なレポートをオンラインで表示するには、表示される[ ライブを表示 ]リンクをコピーして、Webブラウザーのアドレスバーに貼り付けます。
次のコマンドを実行して、リソースの変更を Databricks ワークスペースにデプロイします。
pulumi up
この更新を実行するように求められたら、上方向キーを押して [はい ] に移動し、 Enter キーを押します。 エラーが報告された場合は、それらを修正してからコマンドを再実行します。
PulumiアカウントのPulumiが行ったことの詳細なレポートをオンラインで表示するには、表示される[ ライブを表示 ]リンクをコピーして、Webブラウザのアドレスバーに貼り付けます。
変更されたノートブックをワークスペースに表示するには、表示される [ノートブック URL] リンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。
変更したノートブックでジョブを再実行するには、表示される [ ジョブ URL ] リンクをコピーし、Web ブラウザーのアドレス バーに貼り付けます。 次に、ジョブ ページの [ 今すぐ実行 ] ボタンをクリックします。
ジョブの実行が完了したら、ジョブの実行結果を表示するには、ジョブ ページの [完了した実行 (過去 60 日間)] ボックスの一覧で、[開始時刻] 列の最新の 時刻 エントリをクリックします。 [ 出力 ] ウィンドウには、指定した DataFrame の内容を出力するノートブックのコードを実行した結果が表示されます。
ステップ 6: クリーンアップ
このステップでは、Databricks ワークスペースからノートブックとジョブを削除し、 pulumi-demo
プロジェクトとその dev
スタックを Pulumi アカウントからオンラインから削除するように Pulumi に指示します。
次のコマンドを実行して、Databricks ワークスペースからリソースを削除します。
pulumi destroy
この削除を実行するように求められたら、上方向キーを押して [はい ] に移動し、 Enter キーを押します。
次のコマンドを実行して、Pulumi
pulumi-demo
プロジェクトとそのdev
スタックを Pulumi アカウントからオンラインで削除します。pulumi stack rm dev
この削除を実行するように求めるメッセージが表示されたら、「
dev
」と入力し、 Enter キーを押します。venv
Python 仮想環境を非アクティブ化するには、次のコマンドを実行します。deactivate
テスティング
Pulumi プロジェクトは、デプロイする前にテストできます。 Pulumi ドキュメントの「Pulumi プログラムのテスト」を参照してください。
Python ベースの Pulumi プロジェクトの単体テストでは、Python テスト フレームワークunittestと Pulumi パッケージのpulumi.runtime名前空間を使用して単体テストを記述および実行できます。 シミュレートされたリソースに対してテストを実行するには、Pulumi (および Databricks) への呼び出しをモックに置き換えます。 Pulumi ドキュメントの「Pulumi プログラムの単体テスト」を参照してください。
次のinfra.py
という名前のサンプル ファイルは、この記事のmain.py
ファイルで宣言されたノートブックとジョブの実装をモック化します。 この例の単体テストでは、 小説、 ジョブの名前、および ジョブ実行が成功した場合の E メール受信者の 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 ドキュメントの次の記事を参照してください。