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_VIEWmode: 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つあります。
--bindを付けない場合、生成した設定を含むバンドルをデプロイすると、既存のジョブは更新されず新しいジョブが作られます。重複したジョブができ、スケジュール付きなら二重実行の原因になります- このコマンドが対応するのは、ノートブックタスクを持つジョブだけです
--bindの代わりに、databricks bundle deployment bindで後から紐づける方法もあります。どちらもaskに入れているので、承認の時点で「既存ジョブに紐づく操作か、新規作成か」を確かめられます。
ルールが止められない呼び出し方がある
denyやaskのBashルールは、Claude Codeが通常書くコマンドの形に一致します。別の書き方をすれば、同じプログラムでも一致しないことがあります。公式の説明でも、これらのルールはプログラムの周りの安全境界ではないとされています。
たとえばdatabricks bundle destroyは、denyに入れても、環境変数や別のラッパー経由の呼び出しまでは止まらない可能性があります。確実に止めたい操作は、次の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のアセットを定義するがあります。