Claude CodeでElasticsearchの非推奨APIを点検する — メジャー更新前の確認
Elasticsearchのメジャーアップグレード前に、deprecation APIの出力とアプリのクエリ・クライアントコードを突き合わせて修正対象を一覧にする手順です。claude -pの構造化出力で作業表を作ります。
Elasticsearchのメジャーバージョンを上げる前に確認すべきことは、サーバー側の設定とインデックスの状態、それにアプリケーションが投げているクエリやクライアントコードの3か所に分かれます。Elasticsearchのdeprecation情報を返すAPIが見るのは、このうち前の2つです。アプリのコードに残った古い書き方は、APIの出力を手がかりにして自分で探すことになります。
この「出力とコードの突き合わせ」は、Claude Codeに向く作業です。claude -pでdeprecationのJSONを読ませ、リポジトリの該当箇所を探させ、修正対象を一覧にします。直す作業そのものは、一覧を人が確認してから始めます。
deprecation APIは何を返し、何を返さないか
ElasticsearchにはGET /_migration/deprecationsがあります。特定のインデックスだけを調べるときはGET /{index}/_migration/deprecationsを使います。次のメジャーバージョンで削除または変更される、クラスター・ノード・インデックスレベルの設定のうち、実際に使われているものを返すAPIです。実行にはmanageクラスター権限が必要です。
返ってくる警告にはlevelが付きます。値はnone、info、warning、criticalの4つです。
deprecation APIのlevelの意味
critical
修正必須
直さないとアップグレードできない
warning
修正推奨
直接上げられるが次のメジャーで挙動が変わる
同じ公式ドキュメントには、このAPIはUpgrade Assistantが間接的に使うことを想定した設計だとも書かれています。直接叩くより、Kibanaの管理画面にあるUpgrade Assistantで読むことが推奨されています。ここで取り上げる使い方は、Assistantの結果とアプリのコードを結びつけるために、JSONを手元に落とす場合です。
見落としやすい点が1つあります。APIが返すのはクラスターに現れた情報だけです。たとえばアプリが廃止予定のパラメーターを付けてリクエストしていても、設定やインデックスには痕跡が残らないので、このAPIには出てきません。リクエスト由来の警告は、deprecation logに記録されます。Upgrade Assistantは、deprecation info APIとdeprecation logsに加えて、Kibanaのdeprecations APIも情報源にしています。
| 見つけ方 | 見えるもの | 見えないもの |
|---|---|---|
| deprecation info API | 見えるもの設定、インデックス、データストリームの状態 | 見えないものアプリが投げるリクエストの書き方 |
| deprecation log | 見えるもの実際に届いたリクエスト由来の警告 | 見えないものまだ実行されていない処理の警告 |
| リポジトリの検索 | 見えるものコードに書かれた呼び出し全般 | 見えないもの実行時に組み立てられるクエリの中身 |
3つは補い合う関係です。Claude Codeを使う価値が出るのは3行目で、deprecation logのメッセージを手がかりに、クエリを組み立てている箇所を絞り込めます。
上げる前に決まっている手順を押さえる
8.xから9.xへ上げる場合の事前準備は、Elasticの公式ドキュメントに順序が決まっています。Claudeに作業を渡す前に、ここだけは人が把握しておくところです。
- 先に8.19.xへ上げる。8.18.0と9.0.0は同時にリリースされたため、8.18.xから9.0.xへの直接アップグレードは許容されるが、9.1.0以降へ上げるには8.19.xが出発点になる
- Upgrade Assistantが報告するcriticalな問題はすべて解消する。互換性のないインデックスが残っているとElasticsearchノードは起動に失敗する
- 7.x以前に作ったインデックスは、reindexするか、削除するか、アーカイブ(読み取り専用化)してから9.xに上げる
- 設定変更やreindexの前に、最新のスナップショットを取る
REST API互換モードという橋渡しも用意されています。リクエストにAcceptヘッダー(本文があるときはContent-Typeも)でapplication/vnd.elasticsearch+json;compatible-with=8を付けると、9.xのサーバーが8.xの書き方を受け付けます。公式のクライアントは、環境変数ELASTIC_CLIENT_APIVERSIONINGをtrueにすると全リクエストで有効にできます。互換性が働いた場合、deprecation logにcompatible_apiのカテゴリで記録されます。ただし、同じ動作は保証されず、長期の方針にはせず、アップグレードの橋渡しとして使うものと公式に明記されています。互換モードが吸収しているリクエストがあれば、あとでコード側の修正対象になります。
手順1: deprecationのJSONを手元に落とす
APIキーの権限はmanageが必要で、読み取り専用ではありません。そのため、クラスターを叩く操作はClaudeに渡さず、人が実行してファイルに保存します。
curl -s -H "Authorization: ApiKey $ES_API_KEY" \
"$ES_URL/_migration/deprecations" > deprecations.json
jq 'def keep: map(select(.level != "none"));
with_entries(.value |= (if type == "array" then keep
else (map_values(keep) | with_entries(select(.value | length > 0))) end))
| with_entries(select(.value | length > 0))' \
deprecations.json > deprecations.filtered.json2つ目のコマンドは、levelがnoneの項目を落として、手を入れる必要がある警告だけを残します。レスポンスのcluster_settings、node_settings、ml_settingsは警告の配列、index_settings、data_streams、templates、ilm_policiesは名前ごとに配列を持つオブジェクトです。jqは型で処理を分けているので、どのセクションも落とさずに絞り込めます。
公式のレスポンス例では、7.xで作ったインデックスは次のように報告されます。
{
"level": "critical",
"message": "Index created before 8.0",
"url": "https://ela.st/es-deprecation-8-reindex",
"details": "This index was created with version 7.8.23 and is not compatible with 9.0. Reindex or remove the index before upgrading.",
"resolve_during_rolling_upgrade": false
}このタイプのcriticalは、アプリのコードを直しても消えません。reindexか削除が要る、データ側の作業です。一方で、messageがクエリDSLのパラメーターや廃止されたAPIを指す警告は、コード側の修正対象になる可能性があります。次の手順で分けます。
手順2: Claudeに修正対象を分類させる
claude -pは標準入力を読めるので、JSONをそのままパイプで渡せます。標準入力の上限は10MBです。超えるとエラーで終了するので、大きなファイルは手順1で絞ってからにします。
分類の結果は、--json-schemaで形を固定すると後工程に渡しやすくなります。次の例は、警告ごとに「コードで直せるか」「データやクラスターの作業か」を判定させます。
cat deprecations.filtered.json | claude -p \
"各警告を分類せよ。area は code(アプリのクエリ・クライアント側で直せる)、\
data(reindexなど。コード修正では消えない)、config(サーバー設定)の\
いずれか。code の場合は grep で探す語を searchTerms に入れる" \
--output-format json \
--json-schema '{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"},"level":{"type":"string"},"area":{"type":"string","enum":["code","data","config"]},"searchTerms":{"type":"array","items":{"type":"string"}}},"required":["message","level","area"]}}},"required":["items"]}' \
| jq '.structured_output' > triage.jsonstructured_outputはスキーマに合う出力が得られたときだけ付くフィールドです。Claudeが依頼を断ったときなどは付かないので、後続のスクリプトでは、フィールドの有無を確かめてから使います。
分類はClaudeの推測を含みます。areaがcodeと判定された項目と、dataと判定された項目を、人が一度ざっと見てから先へ進めます。ここで間違えると、コードを直しても警告が消えない作業に時間を使うことになります。
手順3: 該当コードを探して作業表にする
codeと判定された項目だけを対象に、リポジトリを検索させます。検索と読み取りだけを許可し、書き込みはさせません。
claude -p "triage.json の area が code の項目について、searchTerms を\
リポジトリ内で検索し、該当箇所を file:line と現在の書き方、\
公式の url が示す移行先の書き方の方針で表にして。ファイルは編集しない" \
--allowedTools "Read,Grep,Glob" > upgrade-worklist.md--allowedToolsに列挙したツールは確認なしで使えます。編集系のツールは列挙しないので、claude -pの通常の権限設定では、承認が必要な操作は拒否されます。Claude Code v2.1.302以降では、claude -pは、権限モードの指定がなければManualモードで始まります。誰も承認できない定期実行に回すときは、--permission-prompts noneを足すと、承認待ちになる要求はClaudeに再試行させず拒否されます。このフラグはv2.1.259以降で使えます。
クラスターに触るcurlを拒否したい場合は、プロジェクトの設定に拒否ルールを置きます。
{
"permissions": {
"deny": [
"Bash(curl *)"
]
}
}denyルールは、同じコマンドにマッチするallowルールより優先されます。広いdenyの中に狭い例外を作ることはできません。
出来上がるupgrade-worklist.mdは、たとえば次のような形になります。ここでは表の形だけの例で、実際の内容はクラスターの出力と自分のコードで決まります。
| 警告のmessage | 該当箇所 | 直し方の方針 |
|---|---|---|
| (deprecation APIが返した文言) | 該当箇所search/queries.py:84 | 直し方の方針警告のurlが示す移行先の書き方に置き換える |
| (同上) | 該当箇所indexer/mappings.json | 直し方の方針マッピングの定義を見直す |
取りこぼしを防ぐためにCLAUDE.mdへ書く
リポジトリのCLAUDE.mdに、このアップグレード作業の前提を書いておくと、claude -pのたびに説明しなくて済みます。次はその一例です。
## Elasticsearchアップグレード作業の前提
- 現行は8.19.x、移行先は9.x
- deprecations.json は人が取得する。クラスターへの接続は行わない
- 修正は警告ごとに別コミットにし、コミットメッセージに警告のmessageを書く
- REST API互換モード(compatible-with=8)で動いている呼び出しは、
互換モードを外した状態でもテストが通るように直す最後の項目が重要です。互換モードを有効にしたままテストを通しても、互換モードが吸収しているだけで、9.xの書き方には直っていないことがあるからです。
作業表ができたあとの進め方
一覧をレビューしたら、修正は警告ごとに小さく分けます。1つの警告に対応するコミットを1つにしておくと、挙動が変わったときにどの変更が原因かを切り分けやすくなります。
アップグレードのたびに、リリースごとのbreaking changesも見ます。公式の事前準備ドキュメントには、9.xの目標リリースまでの各リリースのbreaking changesを確認するよう書かれています。たとえば9.4.5と9.5.1の欄には、ILMのallocateアクションにnumber_of_replicasを指定したときauto_expand_replicasが明示的に削除される変更が載っています。deprecation APIには出てこないタイプの変更で、読むのは人の仕事になります。
テスト環境での予行も、公式ドキュメントが挙げる準備です。本番に近い構成のテスト環境で、クライアントの動作まで確かめてから、本番に入ります。
同じ「非推奨の警告を片付ける」作業の進め方は、フレームワーク側にも例があります。Claude CodeでRailsをアップグレードするでは警告の分類と修正を扱い、Claude CodeでReact 19をアップグレードではcodemodの取りこぼしの拾い方を扱っています。Elasticsearchに接続するMCPサーバー自体の非推奨については、Elasticsearch MCPサーバーの使い方にまとめています。
まとめ
メジャーアップグレード前の点検は、deprecation APIでクラスター側、deprecation logでリクエスト側、リポジトリ検索でコード側を見る三層になります。Claude Codeに任せるのは、JSONの分類とコードの検索、作業表づくりまでです。reindexのようなデータ側の作業と、breaking changesの判断は人が持ちます。
互換モードが吸収した呼び出しは、アップグレード後もコード側に直す項目として残ります。作業表の最後の列に、互換モードで動いているかどうかを足しておくと見落としません。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。
- elastic.co/docs/api/doc/elasticsearch/operation/operation-migration-d…
- elastic.co/docs/deploy-manage/upgrade/prepare-to-upgrade
- elastic.co/docs/deploy-manage/upgrade/prepare-to-upgrade/upgrade-assi…
- elastic.co/docs/reference/elasticsearch/rest-apis/compatibility
- code.claude.com/docs/en/headless
- code.claude.com/docs/en/permissions