Claude CodeでArgoCD Applicationマニフェストを書く手順
ArgoCDのApplicationカスタムリソースをClaude Codeで書く手順を、必須フィールドとよくあるミスとともに解説します。
Claude CodeでArgoCD Applicationを書くとは
ArgoCDのApplicationは、GitOpsでKubernetesにデプロイする対象を宣言的に定義するカスタムリソースです。apiVersion: argoproj.io/v1alpha1 と kind: Application を持つYAMLファイル1枚で、どのGitリポジトリのどのパスを、どのクラスタのどの名前空間へ同期するかを表します。
Claude CodeはこのYAMLファイルをリポジトリ内の他のマニフェストと同じ手順で編集できます。フィールド名を1つずつ手で調べる代わりに、リポジトリ構成とデプロイ先の情報をプロンプトで渡し、必須フィールドが揃ったApplicationを生成させ、その場でkubectlやargocdコマンドで検証する、という流れです。
前提条件
ArgoCD公式のGetting Startedガイドは、Applicationを作成する前に次を要求しています。
kubectlコマンドラインツールがインストール済みであることkubeconfigファイルが存在すること(既定の場所は~/.kube/config)- クラスタにCoreDNSが有効であること(microk8sの場合は
microk8s enable dns)
さらに、ArgoCD自体がクラスタにインストール済みで、argocd名前空間にサービスが立っている必要があります。ArgoCDのインストール自体はこの記事の対象外ですが、公式手順ではCRD(ApplicationSetなど)がkubectl applyのクライアントサイド処理では262KBの注釈サイズ制限を超えるため、--server-side --force-conflictsフラグ付きでのインストールが案内されています。
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlApplication manifestの必須フィールド
ArgoCD公式のApplication Specificationドキュメントは、Applicationの全フィールドを1枚のサンプルYAMLで示しています。そのうち、Gitリポジトリのマニフェストを同期する最小構成で埋めるのは次の5フィールドです。
| フィールド | 役割 | 例 |
|---|---|---|
metadata.name | 役割Applicationオブジェクトの名前 | 例guestbook |
spec.project | 役割所属するAppProject | 例default |
spec.source.repoURL | 役割マニフェストを置くGitリポジトリ | 例https://github.com/argoproj/argocd-example-apps.git |
spec.source.path | 役割リポジトリ内のマニフェストのパス | 例guestbook |
spec.destination.server | 役割デプロイ先クラスタのAPIサーバーURL | 例https://kubernetes.default.svc |
spec.projectはAppProjectという別のリソースへの参照で、公式のGetting Startedもdefaultプロジェクトを指定しています。spec.destinationはクラスタをserver(APIサーバーURLで指定)またはname(登録済みクラスタ名で指定)のいずれかで示し、ArgoCDが動いているクラスタ自身へデプロイする場合はhttps://kubernetes.default.svcを使います。spec.destination.namespaceは、metadata.namespaceを持たない名前空間スコープのリソースにだけ適用されます。
spec.sourceは単一のGit/Helmリポジトリを指す構文ですが、複数のリポジトリからマニフェストを合成する場合は複数形のspec.sources(リスト)を使う書き方も用意されています。Claude Codeに書かせるときは、単一ソースか複数ソースかを最初のプロンプトで明示しておくと、意図と違う書き方になるのを避けやすくなります。
Claude Codeに書かせる手順
Applicationを書いて同期するまで
- 1
リポジトリ構成をプロンプトで伝える
「
repoURLはこのリポジトリ自身、pathはk8s/guestbook、デプロイ先はhttps://kubernetes.default.svcのguestbook名前空間」のように、Application自身が持つべき値を具体的に渡します。公式サンプルにはHelm用のvalueFilesやparametersも並んでいるので、使う方式(Gitのマニフェスト・Helm・Kustomize)も最初に伝えます。 - 2
生成されたYAMLの2か所だけ先に見る
metadata.nameとspec.destination.namespaceです。取り違えると、想定した名前空間ではなく別の名前空間にリソースが作られます。 - 3
サーバー側のドライランで検証する
クラスタに適用する前に、
kubectl apply --dry-run=serverでAPIサーバー側のバリデーションを通します。kubectl v1.22.5のkubectl apply --helpでは、--dry-runにnone・server・clientを指定でき、serverは「リソースを永続化せずにサーバー側へリクエストを送る」と説明されています。 - 4
Gitにコミットしてから登録する
Application自身もGitで管理された状態から
kubectl applyで登録します。argocd app createで作る方法もあります。 - 5
初期状態を確認して同期する
登録直後のApplicationは、Sync StatusがOutOfSync、Health StatusがMissingと表示されます。
argocd app syncを実行すると、リポジトリのマニフェストを取得して適用します。
kubectl apply --dry-run=server -f guestbook-app.yaml
kubectl apply -f guestbook-app.yaml
argocd app get guestbook
argocd app sync guestbookargocd app createで作成したApplicationの定義はGitに残りません。YAMLとしてリポジトリにコミットしてから適用するほうが、GitOpsの構成管理という目的に合います。
syncPolicyでデプロイの自動度を決める
spec.syncPolicyは、Gitの変更をどこまで自動でクラスタへ反映するかを決めるフィールドです。省略すると同期方針はManualになり、Git側が変わっても手動でSyncボタンやコマンドを実行するまでクラスタには反映されません。argocd app getの出力ではSync Policyの行が<none>と表示されます。
自動化したい場合はautomatedブロックを追加します。
spec:
syncPolicy:
automated:
enabled: true
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true各フィールドの既定値と意味は次のとおりです。
| フィールド | 既定値 | 意味 |
|---|---|---|
automated.prune | 既定値false | 意味Git側から削除されたリソースをクラスタ側でも削除するか |
automated.selfHeal | 既定値false | 意味Git変更がないままクラスタ側だけ手で変更された差分を検知して戻すか |
automated.allowEmpty | 既定値false | 意味pruneと組み合わせた自動同期で、対象リソースが0件になることを許可するか |
automated.enabled | 既定値true | 意味falseにするとpruneなどを書いていても自動同期は動かない |
syncOptionsのCreateNamespace=true | 既定値未指定 | 意味spec.destination.namespaceで指定した名前空間が無ければ自動作成するか |
CreateNamespace=trueを入れ忘れると、デプロイ先の名前空間がまだクラスタに存在しない場合に同期が失敗します。事前に名前空間を作る手間を省きたいなら、この1行をsyncOptionsに加えます。ラベルや注釈を付けたい場合は、managedNamespaceMetadataを併用します。ただしこれはCreateNamespace=trueのときだけ有効です。
自動同期が失敗したときの再試行は、公式サンプルのコメントによると既定で5回、間隔は5秒・10秒・20秒・40秒・80秒です。retryフィールドでlimitやbackoffを変えられます。
完成イメージ: 最小構成のApplication YAML
ここまでのフィールドを1つのファイルにまとめると、次のような形になります。Claude Codeに書かせた結果がこの構造に近いかを、まず目視で確認します。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
labels:
team: platform
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
syncPolicy:
automated:
enabled: true
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=truemetadata.labelsはApplicationオブジェクトに任意のラベルを付与するフィールドです。spec.infoフィールドを使うと、Application詳細画面に任意のリンクやメモを追加表示することもできます。
spec.revisionHistoryLimitは、ロールバック用に保持する過去リビジョンの数を指定するフィールドです。既定値は10で、公式ドキュメントもこの値を増やすことは推奨していません。
CLAUDE.mdにクラスタ構成を書いておく
プロンプトで毎回クラスタURLや名前空間を伝える代わりに、リポジトリのCLAUDE.mdにクラスタ構成を書いておくと、毎回の指示を短くできます。
## ArgoCD Application
- デプロイ先クラスタのAPIサーバーURL: https://kubernetes.default.svc
- 名前空間の命名規則: `<チーム名>-<環境名>`(例: platform-prod)
- syncOptionsには CreateNamespace=true を必ず含めるこう書いておけば、「guestbookアプリをplatformチームのproduction環境に出すApplicationを作って」のような短い指示でも、spec.destination.serverや名前空間の命名、CreateNamespace=trueの付与は、Claude CodeがCLAUDE.mdの規則を読んで補えます。
外部クラスタにデプロイする場合
Application自身はArgoCDが動いているクラスタに置きますが、spec.destinationで指す先は別のクラスタでも構いません。ArgoCDが動いているクラスタ以外にデプロイする場合は、先にそのクラスタの認証情報をArgoCDへ登録しておく必要があります。
kubectl config get-contexts -o name
argocd cluster add <コンテキスト名>この登録によって、対象クラスタのkube-system名前空間にargocd-managerという管理用のServiceAccountが作られ、ArgoCDはこのアカウントのトークンを使ってデプロイと監視を行います。同一クラスタ内にデプロイする場合はこの手順は不要で、spec.destination.serverにhttps://kubernetes.default.svcを指定するだけで済みます。
Helm・Kustomizeのマニフェストを使う場合
spec.source.pathが指すディレクトリがHelmチャートやKustomizeのoverlayの場合は、spec.source.helmやspec.source.kustomizeにレンダリング方法を指定します。Helmチャートの値を上書きしたい場合は、spec.source.helm.valuesObjectにYAMLとして直接値を書くか、spec.source.helm.valueFilesでリポジトリ内の値ファイルを指定します。Claude Codeにプロンプトを渡すときは、「対象パスはHelmチャートで、values-prod.yamlを上書きに使う」のように、どちらの方式で値を渡すかを明示すると、意図した方式で生成されやすくなります。
差分を無視したいとき
HPA(Horizontal Pod Autoscaler)がDeploymentのreplicasを書き換えるケースのように、クラスタ側の変更を意図的に「ズレ」として無視したいフィールドがあります。spec.ignoreDifferencesに対象のグループ・kindとJSONポインタを指定すると、その差分はOutOfSync判定から除外されます。ただし公式サンプルのコメントによると、この設定は同期の処理では使われません。
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas同期のときも無視させたいなら、syncOptionsにRespectIgnoreDifferences=trueを足します。この指定が効くのは、リソースがすでにクラスタにある場合です。Applicationを作った直後でライブ状態が無いときは、Git側のマニフェストがそのまま適用されます。
削除したのにリソースが残るのはなぜか
Applicationを削除したときにDeploymentやServiceまで消えるかは、metadata.finalizersと削除の経路で決まります。
Applicationの削除経路
kubectl delete
resources-finalizer.argocd.argoproj.ioが付いているとカスケード削除になり、無ければApplicationだけが消えます。後から付けるならkubectl patch app APPNAME -p '{"metadata": {"finalizers": ["resources-finalizer.argocd.argoproj.io"]}}' --type mergeです。
argocd app delete
--cascadeが既定で、finalizerも自動で付きます。リソースを残すなら--cascade=falseを指定します。
finalizerの既定の伝播方針は、親を消す前に子を消すforeground cascading deletionです。resources-finalizer.argocd.argoproj.io/backgroundを指定するとbackground cascading deletionになります。
つまずきやすい症状と原因
同期と名前空間でつまずく4症状
Gitにpushしても反映されない
argocd app getでSync Policyが<none>なら手動同期の設定です。自動にするにはautomatedブロックを書きます。ignoreDifferencesが同期で無視される
差分の判定だけに使われ、同期の適用では使われません。
RespectIgnoreDifferences=trueを足します。ApplicationSet配下で自動同期の設定が効かない
ApplicationSetが管理するApplicationでは、
spec.syncPolicy.automatedを変えても効果がありません。切り替えはApplicationSet側で行います。2つのnamespaceを取り違える
metadata.namespaceはApplication自身の置き場所(通常はargocd)です。spec.destination.namespaceは、デプロイされるリソースの置き場所を指します。
クラスタ操作まで自動化したい場合
この記事で扱ったのは、GitリポジトリにApplicationのYAMLをコミットしてargocdコマンドで適用する、GitOpsの標準的な流れです。Application自体の作成や同期実行までClaude Codeのチャットから直接指示したい場合はArgoCD MCPサーバーでGitOpsデプロイをClaudeに任せる、デプロイ先のKubernetesクラスタ自体を操作したい場合はKubernetes MCPサーバーでClaudeからクラスタを操作するが参考になります。書き上げたマニフェストをコミットしてPRにする手順はClaude CodeでPRを作成する手順にまとめています。
まとめ
最小構成は5フィールドで足りるので、Claude Codeには値を具体的に渡し、--dry-run=serverで検証してからコミットする流れが基本です。自動同期とfinalizerは、省略したときの既定(手動同期・非カスケード)が運用に合うかを確かめてから、必要なぶんだけ足します。