Claude CodeでHelmチャートを作成する手順
Claude Codeにhelm createの骨格を実装させ、values.yamlの設計からhelm lint/templateでの検証までを手順化します。
Claude Codeにhelm createの骨格を実装させると、テンプレートの記述とvalues.yamlの設計を一度に進められます。この記事では、チャートの骨格作成からテンプレート実装、values.yamlの設計、helm lint/templateによる検証までを手順化します。
Claude CodeでHelmチャートを作るとはどんな作業か
Helmチャートは、Kubernetesにデプロイする一連のリソースをテンプレート化したパッケージです。Chart.yaml(メタデータ)・values.yaml(デフォルト値)・templates/(テンプレート本体)の3点を軸に構成し、values.yamlの値をテンプレートに埋め込んでKubernetesのマニフェストを生成します。
Claude CodeでHelmチャートを書く作業は、他言語のコードを書かせる作業と同じく通常のコーディング支援として進み、Chart.yamlや.tplファイルの生成そのものに専用の操作は挟まりません。したがって精度を左右するのは、対象リソースの種類・値のうちどれを外部から上書き可能にしたいか・既存の命名規則をどこまで示すかを、どれだけ具体的に伝えるかです。
Kubernetesクラスタ自体をClaudeから直接操作したい場合は、チャートを書く作業とは別の選択肢としてKubernetes MCPサーバーでClaudeからクラスタを操作するという手段もあります。同記事のMCPサーバーはHelmリリースのインストール・削除にも対応しますが、本記事が扱うのはチャート自体をゼロから書く作業です。
前提条件
Helmチャートの雛形生成にはHelm CLIのインストールが必要です。Macではbrew install helm、その他の環境は公式のインストールガイドに従います。
brew install helmhelm lintやhelm templateによるテンプレートのレンダリング確認はKubernetesクラスタへの接続を必要としませんが、実際にhelm installまで進める場合はクラスタへの接続とkubectlの設定が必要です。まずはクラスタなしで書き進め、最後にインストールで確認する進め方がこの記事の流れです。
手順1: helm createで骨格を作り、Claude Codeにテンプレートを実装させる
最初にhelm createでチャートの骨格を作ります。指定した名前のディレクトリにChart.yaml・values.yaml・charts/・templates/・templates/tests/・.helmignoreが生成されます。
helm create mychart生成直後のmychart/templates/には、すでにNOTES.txt(インストール後に表示するヘルプテキスト)・deployment.yaml(Deploymentの基本マニフェスト)・service.yaml(Serviceのマニフェスト)・_helpers.tpl(テンプレート間で再利用するヘルパー)の4つが含まれています。公式のチュートリアルではゼロから書く練習のためにこれらを一度削除しますが、実運用のチャートを書くときは基本形として残し、そこから編集していくのが基本の進め方です。
Claude Codeにテンプレートの実装を依頼するときは、対象リソースの種類と、どの値を外部から変えられるようにしたいかを伝えます。
ConfigMapのテンプレートを追加して。データキーはfavoriteDrinkで、値はvalues.yamlから読み込むようにしてたとえば次のような形になります(Helm公式チュートリアルのConfigMap例と同じ構成)。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
favoriteDrink: {{ .Values.favoriteDrink | quote }}{{ .Release.Name }}はHelmの組み込みオブジェクトで、helm install時に指定したリリース名がそのまま入ります。同様に{{ .Chart.Name }}-{{ .Chart.Version }}と書けばChart.yamlに書いたチャート名とバージョンが展開されます。ReleaseオブジェクトにはRelease.Namespace(デプロイ先の名前空間)・Release.IsUpgrade(アップグレードまたはロールバックの実行時にtrue)・Release.IsInstall(新規インストール時にtrue)といったフィールドもあり、条件分岐が必要なテンプレートではこれらを使って処理を切り替えられます。
複数のテンプレートで同じラベルやリソース名の組み立てを繰り返す場合は、その組み立てロジックを_helpers.tplに1つ定義し、各テンプレートからincludeで呼び出すよう指示すると、命名規則がテンプレート間でずれません。Claude Codeに複数リソースを書かせるときは、「ラベルの組み立てを_helpers.tplに集約して」と条件を添えるのが有効です。
Chart.yamlの必須フィールドはapiVersion・name・versionの3つで、descriptionや対応するkubeVersion(SemVer範囲)は任意です。Claude CodeにChart.yamlを書かせる際も、この3つが埋まっているかを確認します。
手順2: values.yamlの設計をClaude Codeに任せる
values.yamlの構造は、テンプレート側の参照方法や後からの上書き方法まで左右します。公式のベストプラクティスに沿って条件を伝えると、Claude Codeが生成する構造も安定します。
命名規則: 変数名は小文字始まりのキャメルケースにします(chickenNoodleSoupのように)。ハイフンを含む名前や先頭大文字の名前は避けます。Helmの組み込み変数(Release.Nameなど)はすべて大文字始まりなので、ユーザー定義値と衝突しません。
フラットかネストか: 関連する値がすべて必須でない限り、ネストよりフラットな構造を優先します。server.nameのようにネストすると、テンプレート側で{{ if .Values.server }}のような存在確認を毎階層で書く必要があり、serverNameのようにフラットならその確認を省けます。関連する値が多く、そのうち少なくとも1つが必須である場合に限り、ネストで可読性を上げる選択肢が出てきます。
文字列は明示的にクオートする: YAMLの型変換は直感に反する場合があります。foo: falseとfoo: "false"は別の値になり、foo: 12345678のような大きな整数は指数表記に変換されることもあります。文字列は明示的にクオートし、それ以外は暗黙の型に任せる、という原則がもっとも安全です。
values.yamlの値は-fで渡すファイルだけでなく、--setオプションでも上書きされます。配列(リスト)は--set servers[0].port=80のようにインデックス指定が必要になり扱いにくいため、キーで指定できるマップ構造の方が上書きしやすくなります。
必要に応じてvalues.schema.jsonを置くと、values.yamlの構造をJSON Schemaで強制できます。任意のファイルですが、Claude Codeに複数人で使うチャートを書かせる場合は、スキーマ生成もあわせて依頼すると値の取り違えを防げます。
手順3: helm lint/templateでクラスタなしに検証する
テンプレートとvalues.yamlを書いたら、クラスタに繋がなくても検証できる2つのコマンドで確認します。
| コマンド | 検証する内容 | クラスタ接続 |
|---|---|---|
helm lint | 検証する内容チャートが構文的に正しく作られているかの一連のテスト | クラスタ接続不要 |
helm template | 検証する内容値を展開したマニフェストをローカルで表示 | クラスタ接続不要 |
helm install --dry-run=server | 検証する内容Kubernetes API側でのスキーマ検証まで含めた確認 | クラスタ接続必要 |
helm lintは、インストールに失敗する不備があれば[ERROR]、規約や推奨から外れる程度の問題は[WARNING]として報告します。
helm lint mycharthelm templateはクラスタから本来取得する値をローカルでダミー値に置き換えてレンダリングするだけで、対応するAPIが実際にクラスタ側に存在するかまでは検証しません。生成されるYAML自体を目で確認したいときに使います。
helm template mychartインストールせずに生成マニフェストだけを確認したい場合は、helm installに--debugと--dry-runを組み合わせます。--dry-run=clientはクラスタに接続せずクライアント側だけで検証し、--dry-run=serverはクラスタに接続してAPIサーバー側の検証まで行います。--dry-runはSecretsの内容も含めて出力するため、機密情報が混ざる場合は--hide-secretを併用します。
helm install mychart ./mychart --debug --dry-run=server3つを組み合わせると、構文レベルの不備はlint、レンダリング結果の目視確認はtemplate、クラスタ側での適合性は--dry-run=serverという役割分担になります。チャートを書き直した直後はlintとtemplateだけで十分な場合が多く、--dry-run=serverはクラスタに接続できる環境まで進んだ段階で使います。
一連のファイル一式が整い、検証も通ったら、変更をコミットしてPRを作る作業もClaude Codeに任せられます。手順はClaude CodeでPRを作成する手順にまとめています。
手順4: lintとtemplateをClaude Code自身に反復実行させる
手順3の2コマンドは、Claude Codeに手元で打たせることもできます。Bashツールでコマンドを実行できる状態であれば、helm lintとhelm templateをClaude Code自身に実行させ、出力された[ERROR]や[WARNING]、レンダリング結果を読ませて該当箇所を直させる、という反復に持ち込めます。
mychartに対してhelm lintとhelm templateを実行して、出たERRORとWARNINGを直して。直したら両方をもう一度実行して確認してこうした指示を出せば、helm lintの[ERROR]・[WARNING]を読んで該当するテンプレートやvalues.yamlを直し、再度lintとtemplateを実行して確認するところまでを一度の依頼で任せられます。人がコマンドを1つずつ打ち、出力をコピーして渡す手間を省けます。
このやり取りを何度も繰り返すなら、helm lintとhelm templateの実行確認を毎回省く設定も有効です。プロジェクトの.claude/settings.jsonのpermissions.allowに次の2行を加えると、以後この2コマンドは確認なしで実行されます。
{
"permissions": {
"allow": [
"Bash(helm lint *)",
"Bash(helm template *)"
]
}
}*はサブコマンドより後ろに置くのが安全です。Bash(helm *)と書くとhelm installやhelm uninstallまで含めて全許可になってしまうため、検証用の2コマンドだけを許可するなら上記のようにlint・templateの後ろに*を置きます。
命名規則やvalues.yamlの構造方針(フラット優先・キャメルケースの命名・文字列の明示クオート)も、都度の指示に書く代わりにプロジェクトのCLAUDE.mdに一度書いておくと、以後Claude Codeに新しいテンプレートを書かせるときにその条件を省けます。CLAUDE.mdはビルドコマンドやコーディング規約のように「セッションをまたいで常に守ってほしいこと」を書く場所で、チャートの命名・values設計方針もこれに当たります。
よくあるつまずき
Release.IsUpgradeをアップグレード専用のフィールドだと思い込むと落とし穴になります。helm upgradeだけでなくhelm rollback実行時にもtrueになるためです。ロールバックの分岐が必要なテンプレートでRelease.IsUpgradeだけで判定すると、ロールバック時の処理が意図せず一緒に走ることがあります。
Chart.yamlのkubeVersionは任意項目なので、書かないままでもチャート自体は作れます。ただし対応するKubernetesのバージョン範囲を指定しておかないと、非対応のクラスタへ気づかずインストールしてしまう余地が残ります。対応させたいバージョン範囲が決まっているなら、Claude Codeに書かせる際にその範囲を伝え、kubeVersionを埋めるよう条件を添えます。
まとめ
Claude CodeでHelmチャートを作るときは、helm createで骨格を作った上で既定テンプレートを土台にテンプレートを実装させ、values.yamlはフラットな構造・キャメルケースの命名・文字列のクオートという公式の指針に沿って設計させるのが安定した進め方です。クラスタに繋がなくてもhelm lintとhelm templateで検証できるので、この2つはClaude Code自身に実行させて[ERROR]・[WARNING]を直させ、必要に応じて--dry-run=serverでクラスタ側の適合性まで確認します。命名規則やvalues.yamlの構造方針はCLAUDE.mdに書いておくと、以後の指示が短くなります。