Claude Media
Claude CodeでDatabricks Asset Bundlesを書く — deployは承認制に

Claude CodeでDatabricks Asset Bundlesを書く — deployは承認制に

Claude CodeにDatabricksのジョブ定義を書かせる際、bundle validateとplanは自走、deploy・runは承認、destroyは禁止にする権限設定とCLAUDE.mdの書き方を示します。

Databricksのジョブ定義をClaude Codeに書かせるなら、databricks bundle validateとdatabricks bundle planは確認なしで回し、deployとrunは毎回承認、destroyは禁止にする構成が扱いやすくなります。前の2つはワークスペースを変更せず、後の3つはジョブの作成・実行・削除に直結するからです。この記事は、その線引きを.claude/settings.jsonとCLAUDE.md、databricks.ymlに落とす手順をまとめます。

Declarative Automation Bundlesとは何か

Declarative Automation Bundlesは、Databricksのジョブやパイプラインをソースファイルとして記述し、ソース管理・コードレビュー・テスト・CI/CDに乗せるための仕組みです。以前の名称はDatabricks Asset Bundlesで、検索や過去の記事ではこの旧名が今も使われます。中身は同じものです。

プロジェクトのメタデータはYAMLで書きます。Databricks CLIがそのYAMLを検証し、デプロイし、実行します。Databricks CLIの機能なので、CLIはバージョン0.218.0以上が必要です。ワークスペース側ではワークスペースファイルが有効になっている必要があります。

最初の一歩はdatabricks bundle initでテンプレートから作る方法です。手書きでもよく、その場合はプロジェクトのルートにdatabricks.ymlを置きます。Claude Codeに書かせる対象は、このdatabricks.ymlと、そこから読み込まれるリソース定義のYAMLです。

Databricksを別の面から使う方法は既に記事にしてあります。SQLやUnity CatalogをClaudeから操作したいときはDatabricks MCPサーバーでClaudeからSQLとUnity Catalogを操作するが向き、この記事は「定義ファイルを書いてCLIで反映する」側を扱います。

コマンドを「読むだけ」「作る」「消す」に分ける

bundleのコマンドは、ワークスペースへの作用で分けると権限ルールに落としやすくなります。

区分コマンドワークスペースへの作用
検証コマンドbundle validateワークスペースへの作用設定ファイルの構文を確認し、IDの要約を出す
検証コマンドbundle planワークスペースへの作用実行される操作を表示し、変更はしない
検証コマンドbundle summaryワークスペースへの作用バンドルのIDとリソースの要約だけを出す
反映コマンドbundle deployワークスペースへの作用ジョブやパイプラインを作成・更新・削除する
反映コマンドbundle runワークスペースへの作用ジョブやパイプラインを実際に動かす
取り込みコマンドbundle generate / bundle deployment bindワークスペースへの作用既存リソースの設定を取得し、紐づける
破棄コマンドbundle destroyワークスペースへの作用デプロイ済みのジョブ・パイプライン・成果物を完全に削除する

validateは、リソースのプロパティがスキーマに無いときに警告を出します。タイプミスしたキーを見つける用途に向いています。出力例にはワークスペースのホストとユーザーが含まれるので、認証が効いた状態で走る前提で考えます。

planはdeployの前に、作る・更新する・消す操作を一覧します。create jobs.my_bundle_jobのような行が並び、何も変更しません。デプロイは「設定にあって既存に無いものは作り、設定から消したものはワークスペースからも消す」ので、planで削除が混ざっていないかを見るのが有効です。

destroyは取り消せません。公式の説明どおり、デプロイ済みのジョブ・パイプライン・成果物を完全に削除します。Claude Codeには持たせない操作の筆頭です。

settings.jsonに書く権限ルール

権限ルールはdeny、ask、allowの順に評価され、最初に一致したものが結果を決めます。広いdenyは、より狭いallowがあっても優先されます。この性質を使い、「読むだけ」をallow、「作る」をask、「消す」をdenyに置きます。

{
  "permissions": {
    "allow": [
      "Bash(databricks bundle validate *)",
      "Bash(databricks bundle plan *)",
      "Bash(databricks bundle summary *)",
      "Bash(databricks bundle schema *)"
    ],
    "ask": [
      "Bash(databricks bundle deploy *)",
      "Bash(databricks bundle run *)",
      "Bash(databricks bundle generate *)",
      "Bash(databricks bundle deployment *)"
    ],
    "deny": [
      "Bash(databricks bundle destroy *)"
    ]
  }
}

Bash(databricks bundle validate *)は、引数なしのdatabricks bundle validateにも一致します。-t devのようなオプション付きの呼び出しも同じルールで拾えます。*はサブコマンドの後ろに置いています。databricks * validateのようにサブコマンドの前へ置くと、許可の範囲が広がりすぎるためです。

bundle schemaは設定のJSONスキーマを出力するコマンドです。Claude Codeにスキーマを読ませて、databricks.ymlに書けるキーを確かめさせる用途で使えます。

deployをaskにしているので、Claude Codeがdeployを呼ぶたびに承認画面が出ます。承認時に見るのは、コマンドにある-tの値です。-t prodが付いていたら、本番への反映なので内容を確かめてから進めます。

databricks.ymlでdevとprodを分ける

権限ルールだけでなく、bundle側にも「うっかり本番を動かさない」設計を入れておきます。targetsでdevとprodを分け、それぞれにデプロイモードを付けます。

bundle:
  name: etl-bundle
 
include:
  - resources/*.yml
 
targets:
  dev:
    mode: development
    default: true
 
  prod:
    mode: production
    git:
      branch: main
    workspace:
      host: https://<production-workspace-url>
    run_as:
      service_principal_name: <service-principal-name>
    permissions:
      - group_name: data-engineers
        level: CAN_VIEW

mode: developmentでデプロイすると、次の動作が入ります。

  • ノートブックやファイル以外のリソース名の先頭に[dev <ユーザー名>]が付き、ジョブとパイプラインにdevタグが付く
  • スケジュールとトリガーが一時停止になる
  • 同時実行が有効になり、デプロイのロックが無効になる

つまり、Claude Codeがdevに向けて試行錯誤しても、本番のジョブと名前がぶつからず、勝手に定時実行が始まることもありません。

mode: productionでは検証が厳しくなります。パイプラインがdevelopment: falseになっているか、現在のGitブランチがtargetのgit.branchと一致しているかが確かめられます。ブランチが違うと、--forceを付けない限りデプロイは進みません。

本番の実行主体はrun_asでサービスプリンシパルにするのが推奨されています。run_asを使わない場合は、run_asとpermissionsを明示するよう検証されます。run_asがデプロイするIDと異なるとき、対応するリソースはジョブとパイプラインだけになる点にも注意が要ります。モデルサービングエンドポイントを含むバンドルでは、run_asを設定するとエラーになります。

default: trueは、-tを省略したときに使われるtargetを決めます。devに付けておけば、-tを忘れた呼び出しもdevに向かいます。

CLAUDE.mdに検証の順序を書く

権限ルールは「何を許すか」を決めるだけで、「どの順で進めるか」は決めません。順序はCLAUDE.mdに書きます。

## Databricks bundle
 
- ジョブ定義は `resources/*.yml` に置き、`databricks.yml` から include する
- YAMLを編集したら、必ず `databricks bundle validate -t dev` を実行して警告を読む
- 警告が出たら、スキーマ未定義のキーかタイプミスを疑って修正してから次へ進む
- `deploy` の前に `databricks bundle plan -t dev` を実行し、削除(delete)の行が含まれていないか報告する
- `deploy` と `run` は承認が必要。対象は必ず `-t dev`。`-t prod` は指示があるときだけ
- `bundle destroy` は実行しない
- `--auto-approve` と `--force` は付けない

検証→報告→承認の順を決めておくと、Claude Codeの作業は「編集、validate、修正、plan、承認待ち」の周回になります。validateの警告が減るまで自走し、planの結果を人に見せた時点で止まります。

編集のたびにvalidateを呼ばせたいときは、hookで機械的に走らせる手もあります。PostToolUseのhookは、Claude Codeがファイルを書き換えた直後に動きます。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "if": "Edit(*.yml)",
            "command": "databricks bundle validate -t dev"
          }
        ]
      }
    ]
  }
}

ifはパーミッションルールの書式で絞り込む欄で、YAMLを編集したときだけvalidateが走ります。validateはワークスペースの認証を使うため、認証が切れていると編集のたびに失敗します。まずはCLAUDE.mdの指示だけで回し、取りこぼしが出てから足す順が無難です。

認証は「どのprofileで動くか」を先に確かめる

bundleのコマンドは、-pで指定しなければ、設定ファイルにあるDEFAULTプロファイルを使います。Claude Codeが何も指定せずにdatabricks bundle deployを呼べば、DEFAULTの指すワークスペースが対象になります。

公式は、手元の開発ではOAuthのユーザー認証(U2M)を、CI/CDのような無人実行ではサービスプリンシパルのOAuth(M2M)を勧めています。手元でClaude Codeを動かす場合も、開発用のプロファイルをDEFAULTにしておくと、取り違えが起きにくくなります。

本番ワークスペースの認証情報は、Claude Codeを動かす端末に置かない運用が安全です。本番への反映は、CI/CDのサービスプリンシパルに任せる形になります。Claude Codeはdevでvalidateとplanまでを自走し、本番へはプルリクエストを通して反映させる流れです。

既存ジョブはgenerateで取り込み、bindまで確認する

すでにワークスペースにあるジョブをbundle化するときは、databricks bundle generate jobを使います。ジョブIDを渡すと、リソースの設定をresourcesフォルダーのYAMLに書き出し、参照されているノートブックもsrcにダウンロードします。

databricks bundle generate job \
  --existing-job-id 6565621249 \
  --bind

注意点が2つあります。

  1. --bindを付けない場合、生成した設定を含むバンドルをデプロイすると、既存のジョブは更新されず新しいジョブが作られます。重複したジョブができ、スケジュール付きなら二重実行の原因になります
  2. このコマンドが対応するのは、ノートブックタスクを持つジョブだけです

--bindの代わりに、databricks bundle deployment bindで後から紐づける方法もあります。どちらもaskに入れているので、承認の時点で「既存ジョブに紐づく操作か、新規作成か」を確かめられます。

ルールが止められない呼び出し方がある

denyやaskのBashルールは、Claude Codeが通常書くコマンドの形に一致します。別の書き方をすれば、同じプログラムでも一致しないことがあります。公式の説明でも、これらのルールはプログラムの周りの安全境界ではないとされています。

たとえばdatabricks bundle destroyは、denyに入れても、環境変数や別のラッパー経由の呼び出しまでは止まらない可能性があります。確実に止めたい操作は、次の2段で守ります。

  1. 権限ルールで通常の呼び出しを止める
  2. 認証情報を渡さない。devのワークスペースしか触れないプロファイルにすれば、destroyが実行されても影響はdevに閉じる

もう1つ、オプションの扱いに注意が要ります。bundle deployには、承認を省く--auto-approve、Gitブランチの検証を上書きする--force、デプロイのロックを強制取得する--force-lockがあります。いずれも「安全装置を外す」オプションです。CLAUDE.mdに使わない旨を書き、承認画面で見かけたら止めるのが基本になります。

bundle deploy --selectは特定のリソースだけをデプロイするオプションで、開発ワークスペース向けと説明されています。本番では想定されていません。依存先の更新が漏れて、予期しない挙動になる可能性があるためです。

よくあるつまずき

validateは通るのに、デプロイ時に落ちる。 validateの説明は「設定ファイルが構文として正しいかを確認する」ことです。ワークスペース側の状態までは確認の対象として書かれていません。planを挟み、それでも落ちるときはクラスターIDや権限など、ワークスペース側を確認します。

devで定時実行が動かない。 mode: developmentではスケジュールとトリガーが一時停止になります。個別に動かしたいジョブは、schedule.pause_statusをUNPAUSEDにします。

リソース名を変えたら別のジョブができた。デプロイは、リソースを名前ではなくIDで追跡します。bundleの名前、target、ワークスペースのいずれかが変わると、前回のデプロイとの関連づけが切れます。

同じ名前のバンドルが互いに上書きし合う。バンドルの同一性は、デプロイするIDとバンドル名、target名で決まります。これらが同じだと、別のバンドルでもデプロイが干渉します。

前回のデプロイがロックを残した。異常終了のあとは--force-lockが必要になることがありますが、Claude Codeに自動で付けさせない方が安全です。ロックを手で外すのは人の判断にします。

Claude Codeがdatabricks.ymlの書き方を間違える。 bundle schemaの出力を読ませるか、bundle initが作るテンプレートを雛形にして、差分を書かせる形が確実です。

まとめ

Databricksのbundleは、validateとplanが変更を伴わず、deployとrunが作用を持ち、destroyが取り消せないという3層でできています。権限ルールをこの3層に合わせれば、Claude Codeは検証の周回を自走し、反映だけを人が承認します。

設計の要点は3つです。権限はallow・ask・denyで3層に分ける。devとprodをmodeで分け、prodにはrun_asのサービスプリンシパルを置く。認証は、Claude Codeが触れるワークスペースをdevに閉じる。同じ型でAWSのLambdaを扱う手順はClaude CodeでAWS Lambda(SAM)を開発にあります。

パイプラインを宣言的に定義する別のツールをClaude Codeで扱う例としては、Claude CodeでDagsterのアセットを定義するがあります。

この記事を共有:XはてブLinkedIn