😺

Databricks各種リソースをPulumiでプロビジョニングする

2024/05/19に公開

はじめに

データ処理/DWH/分析/MLらをワンストップで担うことができるDatabricksには Compute, Workflow, Dashboardなど多様なリソースが存在します。
これらのリソースは、GUI(Graphical User Interface) はもちろん、CLI(Command Line Interface)やIaC(Infrastructure as Code) を用いた作成も可能です。
本稿では、各作成手段について簡易に特徴と私見を述べた後、IaC の一つであるPulumiを用いてDatabricks SQL Warehouseをプロビジョニングします。

Databricks ワークスペース内リソース作成手段

Databricks ワークスペース内のリソースを作成する手段は以下の3種に大別できます。

  1. GUI
  2. CLI
  3. IaC

これらは最終的にREST APIをコールしリソースを作成するため、おおまかには、REST APIが最もプリミティブなもの、他のものはREST APIを抽象化したものと捉えることができます。
各々の特徴を見ていきましょう。

1. GUI

ほとんどすべての人が経験しているであろうリソース作成手段です。

ドキュメントや事前学習なしで直感的に作成できるものが多いため、敷居が最も低いというメリットがあります。

一方で、他の方法に比較し、再現性、再利用性(ただし、リソースによってはCloneすることが可能)や変更管理の難易度が高くなります。
具体的な例でいうと、「以前作成したリソースを再現したいが、UIに変更が入った」や「操作ミスによる意図しない変更から復元したい」等のケースです。
これらへの対策は「注意して作業をする。」となりがちなので、Production相当の環境おいては、可能であれば他のリソース作成手段をとりたいところです。

また、GUIではリソース作成/変更が不可能なケースも存在します。以下に例示します。

2. CLI

もっともプリミティブなREST APIとそれをラップしたDatabricks CLIがこの手段に該当します。

実行コマンドをスクリプトの形で残しておくことができるため、再現性、再利用性の観点でGUIに勝ります。
また、もっともプリミティブな手段のため、「CLIで不可能な作成/変更作業はない。(=CLIできないことは他の手段でもできない。)」といって差し支えないでしょう。

一方で、ドキュメントの参照必須なため、直感でも作業可能なGUIに比べると敷居は高くなります。
また、CLIを複数組み合わせるような複雑なリソース作成/変更のケースでは、実行順序(依存関係)や失敗時のロールバックを考慮する必要があり、スクリプトが煩雑になりがちです。

3. IaC

さまざまな IaCが存在しますが、公式ドキュメントでは、Databricks Asset Bundles, Terraform, CDK for Terraform, Pulumiらが紹介されています。

リソースをコードで定義できるため、再現性、再利用性が高いです。
また、使用するものにもよりますが、多くの場合、実行順序も明示的に宣言可能(暗黙的に解決してくれるものもある)、実行失敗時のロールバック時の動作をある程度制御可能なため、CLIに比べ複雑なリソースの管理も容易になります。
さらに、リソースの作成/変更情報も管理されているため、意図しない変更操作(=ドリフト)も検知可能であり、一貫性も維持しやすいです。
総じて、他の手段と比較しリソースのコントロールに優れます。

一方で、導入から記法の学習までが必須なので、初期ハードルは最も高くなります。
また、作成/変更可能なものはプロバイダに依存します。具体的には、 プレビュー中の機能はCLIのみサポートされているなどのケースが生じることがあります。

各 IaC の特徴を簡易に見ていきます。

Databricks Asset Bundles

2024/04 GA と執筆時点でリリースされて間もないです。
YAML 形式でリソースを宣言的に記述、Databricks CLIでDeployできるため、他のIaCと比較すると 事前準備のハードルが最も低いのではないでしょうか。
Databricks における IaC 活用のメインのどころである、Workflows(Delta Live Tables含む)の作成には対応しているようですが、例えば Databricks SQL Warehouse のみを作成するといったようなケースにはまだ対応していないようです。

また、実際に実行すると、.tfファイルが作成されることがわかります。裏側では、Terraformをコールしているようです。

いずれにせよ登場間もないものなので、今後の発展に注目といったところでしょうか。

Terraform

IaC といったらコレ という方も多いのではないでしょうか。
HCLという形式でリソースを記述しDeployします。
周辺の環境が充実しており、使ってみた等の2次情報も豊富にあるのもメリットです。

AWS CDK のコンセプトを踏襲し、TypescriptやPython等の言語でリソースを宣言した後、最終的にTerraform へ変換するCDK for Terraformといったものも存在します。

Pulumi

Terraformに対し後発なIaCです。 参考:Pulumi 視点での Terraform との違い
Typescript, Python, YAMLなどの様々な言語でリソースを記述できます。

今回はYAMLを利用して、Databricks SQL Warehouseを作成していきます。

Pulumi(YAML)で Databricks SQL Warehouse を作成する

Pulumiを利用して、Databricks SQL Warehouseを作成する手順をウォークスルーします。
なお、詳細は後述しますが、stateはlocalで、シークレットはpassphraseプロバイダを利用します。

## インストール
ドキュメントのとおり、自身の環境にあったセットアップを実施してください。
以下のように version コマンドを実行し、任意のバージョンが返ってくれば正常に実行できています。

$ pulumi version
v3.116.1 # 自身の導入したバージョンが返ってくればOK.

pulumi login

Pulumiでは、リソースの状態のメタデータ(state)を管理します。Terraformでいうtfstateファイルにあたります。
このstateは、Pulumi Cloud, パブリッククラウド(AWS, Azure, Google Cloud)のオブジェクトストレージ, Localのいずれかで管理可能です。

  • Pulumi Cloud

    • Pulumi Managedな環境でstateを管理します。
    • 作成物(stack)を一元的に管理可能で、履歴や状態をリッチなダッシュボードで確認可能です。
    • 使用には、Pulumiアカウントへサインアップする必要があります。
    • 使用方法応じた、料金を支払う必要があります。Pulumi Cloud Pricing
  • パブリッククラウドのオブジェクトストレージ

    • パブリッククラウドのオブジェクトストレージサービスでstateファイルを管理します。
    • 使用には、各オブジェクトストレージの資格情報が必要です。
    • (筆者は普段これを利用しています。)
  • Local

    • localでstateファイルを管理します。
    • 本稿ではこれを利用します。

チームや組織の状態に応じて適切なものを選択した後、以下のドキュメントに従い、loginしてください。

# pulumi cloudを利用する場合
$ pulumi login
# 対話形式のプロンプトが返ってくるので、指示に従いログインしてください。
# パブリッククラウドのオブジェクトストレージを使用する場合
## 各ストレージへの認証方法については併記のドキュメントを参照のこと

## Amazon S3の場合
### https://www.pulumi.com/docs/concepts/state/#aws-s3
$ pulumi login s3://<bucket-name>

## Azure Blob
### https://www.pulumi.com/docs/concepts/state/#azure-blob-storage
$ pulumi login azblob://<container-path>

## Google Cloud Storage
### https://www.pulumi.com/docs/concepts/state/#google-cloud-storage
$ pulumi login gs://<my-pulumi-state-bucket>
# localを利用する場合
$ pulumi login --local

ログイン情報はwhoamiで確認できます。

$ pulumi whoami -v
# pulumi cloudへログインした場合の返り
User: <your-username>
Backend URL: https://app.pulumi.com/<your-username> 

プロジェクトの開始(pulumi new)

スクラッチでPulumiを記述していく場合、pulumi newによりスケルトンを生成できます。
すでにコードが存在する場合、本手順はスキップ可能です。
ドキュメントに従い進めていきましょう。

今回は、 pulumi/sql_warehouseの配下にYAMLのスケルトンを作成し、そのスケルトンに肉付けしていきます。

# 任意のディレクトリの作成と移動 
$ mkdir -p pulumi/sql_warehouse && cd $_

$ pulumi new
# 対話形式のプロンプトが返ってくるので、入力していく
## 今回は指定したのは以下の通り
## 作成するスケルトン:yaml
## project_name: sql_warehouse #親ディレクトリと同じ名前
## project_description: デフォルトのまま
## stack_name: dev
## passphrase: 任意のphrase。記憶しておくこと。(後述)

成功すると、作成したディレクトリ配下に2つの.yamlが作成されます。

  • Pulumi.yaml
    • 形式に沿ってリソースを定義するファイル
pulumi/sql_warehouse/Pulumi.yaml
name: sql_warehouse
runtime: yaml
description: A minimal Pulumi YAML program
config: {'pulumi:tags': {value: {'pulumi:template': ""}}}
outputs: {}
resources: {}
variables: {}
  • Pulumi.{stack_name}.yaml
    • deployする環境に応じたパラメータなどを記載するファイル
pulumi/sql_warehouse/Pulumi.dev.yaml
encryptionsalt: *********************** #ランダムな文字列

(備考)passphraseとencryptionsalt

ここで、pulumi newの実行時に設定したpassphraseと生成したPulumi.dev.yamlに記載されているencryptionsaltの解説をいれておきます。

前述の通り、Pulumi.{stack_name}.yamlへは、環境に応じたパラメータを記載します。
パラメータ中には、平文として保持すべきではないものも存在するでしょう。(例: データベースのパスワード)
そのために、Pulumiでは、これらを暗号化して保存することができます。
つまり、暗号の復号のために、使用されるのがpassphraseencryptionsaltになります。

Pulumi.yamlの記述

ドキュメントを参照しながら、Pulumi.yamlを編集しましょう。

おおよそ以下のようになるでしょう。

pulumi/sql_warehouse/Pulumi.yaml
name: sql_warehouse
runtime: yaml #runtime 今回はyamlを使用
description: databricks warehouse #このファイルの説明

resources:
  # ref. https://www.pulumi.com/registry/packages/databricks/api-docs/sqlendpoint/
  warehouse: #任意の名前。このファイルでは、このリソースをwarehouseという名前で扱うという意。依存などがある場合には、この名前を使って参照する。
    type: databricks:SqlEndpoint #規定された記述。Databricks SQL Warehouseを定義するという宣言。
    properties: #以降は、Databricks SQL Warehouse の設定(プロパティ)を記述する
      name: sample-warehouse #sql warehouseの名前
      clusterSize: 2X-Small #sql warehouseのサイズ
      maxNumClusters: 1 #クラスタ数
      autoStopMins: 1 #自動停止時間(GUIでは、5未満が設定できなかった項目)
      enableServerlessCompute: true #サーバレスを使用するか否か

汎用性に欠けるため、いくつかのプロパティをパラメータ化してみます。
SQL WarehouseのnameclusterSizeをパラメータ化したものが以下です。

pulumi/sql_warehouse/Pulumi.yaml
name: sql_warehouse
runtime: yaml #runtime 今回はyamlを使用
description: databricks warehouse #このファイルの説明

resources:
  # ref. https://www.pulumi.com/registry/packages/databricks/api-docs/sqlendpoint/
  warehouse: #任意の名前。このファイルでは、このリソースをwarehouseという名前で扱うという意。依存などがある場合には、この名前を使って参照する。
    type: databricks:SqlEndpoint #規定された記述。Databricks SQL Warehouseを定義するという宣言。
    properties: #以降は、Databricks SQL Warehouse の設定(プロパティ)を記述する
      name: ${prefix}-warehouse #sql warehouseの名前
      clusterSize: ${clusterSize} #sql warehouseのサイズ
      maxNumClusters: 1 #クラスタ数
      autoStopMins: 1 #自動停止時間(GUIでは、5未満が設定できなかった項目)
      enableServerlessCompute: true #サーバレスを使用するか否か

パラメータの注入

Pulumi.yamlでパラメータ化したものに対し、実際の値を注入します。
config setで注入可能です。

# prefixというパラメータにsampleという値をセット
$ pulumi config set prefix "sample"

# clusterSizeというパラメータに2X-Smallという値をセット
$ pulumi config set clusterSize "2X-Small"

config setの実行後、Pulumi.dev.yamlには、パラメータのキーと値のペアが記述されます。

pulumi/sql_warehouse/Pulumi.dev.yaml
encryptionsalt: *********************** #ランダムな文字列
config:
  sql_warehouse:clusterSize: 2X-Small
  sql_warehouse:prefix: sample

なお、CLIを通さず、直接ファイルを編集しても問題ありません。

Databricksホスト情報と認証情報の注入

最後に、DatabricksワークスペースへDeployするためのDatabricksのホスト情報と認証情報を記載していきます。

Databricksのホスト情報は、DatabricksワークスペースのURLです。

# databricks:hostに自身のワークスペースURLをセット
$ pulumi config set databricks:host <your workspace url> # TODO deploy先のDatabrikcsワークスペースURLに置き換える

Databricksへの認証情報としてはDatabricks Personal Access Tokenがサポートされています。
Databricks SQL Warehouseを作成したいワークスペースから、ドキュメントの通りDatabricks Personal Access Tokenを取得しましょう。

ホスト情報と同様にconfig setにより設定を行いますが、このTokenは平文として保持されるべきでない情報です。--secretオプションを付けて暗号化しましょう。

# databricks:hostにsampleという値をセット
$ pulumi config set databricks: token "<access-token>" --secret # TODO 取得したTokenに置き換える

これらの実行後、Pulumi.dev.yamlは以下のようになります。

pulumi/sql_warehouse/Pulumi.dev.yaml
encryptionsalt: *********************** #マスクしています。
config:
  databricks:host: https://*****************.net #マスクしています。
  databricks:token: 
    secure: ******************* #マスクしています。
  sql_warehouse:clusterSize: 2X-Small
  sql_warehouse:prefix: sample

Deploy(pulumi preview, pulumi up)

最終的に、以下2つのファイルを利用して、Deployします。

pulumi/sql_warehouse/Pulumi.yaml
name: sql_warehouse
runtime: yaml #runtime 今回はyamlを使用
description: databricks warehouse #このファイルの説明

resources:
  # ref. https://www.pulumi.com/registry/packages/databricks/api-docs/sqlendpoint/
  warehouse: #任意の名前。このファイルでは、このリソースをwarehouseという名前で扱うという意。依存などがある場合には、この名前を使って参照する。
    type: databricks:SqlEndpoint #規定された記述。Databricks SQL Warehouseを定義するという宣言。
    properties: #以降は、Databricks SQL Warehouse の設定(プロパティ)を記述する
      name: ${prefix}-warehouse #sql warehouseの名前
      clusterSize: ${clusterSize} #sql warehouseのサイズ
      maxNumClusters: 1 #クラスタ数
      autoStopMins: 1 #自動停止時間(GUIでは、5未満が設定できなかった項目)
      enableServerlessCompute: true #サーバレスを使用するか否か
pulumi/sql_warehouse/Pulumi.dev.yaml
encryptionsalt: *********************** #マスクしています。
config:
  databricks:host: https://*****************.net #マスクしています。
  databricks:token: 
    secure: ******************* #マスクしています。
  sql_warehouse:clusterSize: 2X-Small
  sql_warehouse:prefix: sample

まず、previewを実行してみましょう。
これは、dry-runのようなもので、変更差分を表示してくれます。
実運用時にはお世話になるコマンドです。

$ pulumi preview

previewを確認して問題なさそうであれば、upを実行し、Deployしましょう。

$ pulumi up -f -y

コマンドが正常に完了し、Databricksワークスペースを確認し、sample-warehouseというSQL Warehouseが作成できていれば成功です。

作成できたWarehouse

振り返りと片付け

Pulumiを通じて、SQL Warehouseを作成しました。
stack initによって、新たにstackを作成すればPulumi.yamlを使い回わした上でパラメータのみを変更したSQL Warehouseを作成可能です。

# 新たなスタックを作成する。
$ pulumi stack init
## prd というstackを作成し、
## ホスト名, Token, パラメータを変更すれば異なるワークスペースにもSQL warehouseをDeploy可能。

作成対象の簡易さに比べ、準備作業が大変であったことから旨味を感じないかもしれませんが、適切にパラメータ化されていれば、複雑なリソースの作成においては非常に恩恵が大きくなります。

最後に、destroyで作成したリソースを削除しましょう。

$ pulumi destroy

おわりに

Databricks ワークスペース内リソースの作成手段の簡易な比較と、Pulumiで Databricks SQL Warehouse を作成するのリソース作成をウォークスルーを行いました。
IaCは適切に用いれば、成果物のデリバリにおいて、非常に強力な効果をもたらします。

また、本稿ではPulumiを用いましたが、筆者自身は「チームや組織の構成と開発対象のライフサイクルに応じて使い分ければよい」という考えで、
Databricksワークスペースの作成にはTerraformを、Databricksワークスペース内に作成するリソースはPulumi(YAML)を利用するといったような使いわけをしています。
また、今日明日で消すようなリソースの作成にはGUIもCLIも併用しています。

次回は、これにGitHub Actions組み合わせたCD(Continuous Delivery)を記載します。

Discussion