2025/11/30、EKS Capabilityが発表されました。 Capabilityで実行するコントローラーは、EKS AutoModeの拡張のような形でAWSの保持するEKSが管理する実行環境で実行されるため、ユーザー管理のEKSクラスターではPodが実行されません。 感覚的には、Configurationが乏しいが完全AWS ManagedなEKS Addonのようなイメージです。
今回は、EKS Capabilityで実行するArgoCDはどのような感じなのか見てみましょう。私はOSS版のArgoCDを使っているので違いや制約がとても気になります。
- 短くまとめ
- EKS Capabilityを展開する
- CapabilityのArgoCDにアクセスする
- クラスターの追加
- EKS Access Entryの権限を調整する
- アプリケーションを追加する
- できないこと
- コスト
- TIPS
- まとめ
- 参考
短くまとめ
EKS CapabilityでArgoCDは動きます、しかも悪くない感じです。本番で使うにしても割とありより判断です。気になるところとして、ドキュメントにある制約が、書いてあるより引っかかりやすいです。忘れてはいけないのは、OSS版ArgoCDを見るとわかる通り、ArgoCD自体が多くのコンポーネントを必要として、Podも5台以上必要になることが多いです。Capability版はこれをAWSが管理してくれるので、運用負荷はかなり下がります。
OSS版でPod 0台にしてコストを下げる荒業は、EKS Capability版ではできずコンスタントに常時課金分がかかります。規模が小さいほど、たびたび思い出したように、えーって感じにはなりそう。しょうがない。
〇 よいところ
- EKS CapabilityにセットしたIAM RoleでAWSサービス連携が容易なのは悪くない感じ
- リモートクラスターをEKS Access Entryで登録するのもシンプルな感じでよい
- ArgoCDはコンポーネントが複数あるしアップデートも割と大変なので任せられるのはあり
△ 気になるところ
- インクラスターを登録するのに
AmazonEKSClusterAdminPolicyをEKS Access Entryで紐づけるのは権限が気になる、バグ? - ArgoCD Notificationが使えない (Slack通知で困る)
- 認証バックエンドがIdentity Centerに固定されている (Cognitoなど他IdPを使えない)
- コストがちょっとかかる。Pod分が不要と思えばありな気もしなくはない。(ArgoCDはPod結構必要なので)
気にならない制約
- Namespace supportは別になくても平気なのでよさそう。(ArgoCDのApplicationを複数のnamespaceにデプロイする機能。
argocdnamespaceに集約すればいいので運用上は必須じゃない) - ArgoCD Image Updaterが使えない
EKS Capabilityを展開する
先日リリースされたばかりなので、TerraformやPulumiのようなIaCツールはまだAPIをサポートしていません。ドキュメントに沿って、AWS CLIかコンソールで操作できます。今回は、EKS AutoModeで展開したEKSクラスターに、AWSコンソールからArgoCDを展開します。
ArgoCD Capabilityを展開するには次の手順で進めます。
- EKS CapabilityのためにIAM Roleを用意する
- ArgoCD Capabilityを作成する
EKS CapabilityのためにIAM Roleを用意する
EKS Capabilityは、ユーザー管理EKSクラスターに対して操作するためIAM Roleを必要としているようです。
目新しいのがAsuumeRoleのcapabilities.eks.amazonaws.comです。また、権限にAWSSecretsManagerClientReadOnlyAccessを付けておくと、ArgoCDのリポジトリ参照時にSecrets Managerを参照できます。
apiVersion: v1 kind: Secret metadata: name: private-repo namespace: argocd labels: argocd.argoproj.io/secret-type: repository stringData: type: git url: https://github.com/org/repo secretArn: arn:aws:secretsmanager:ap-northeast-1:012345689:secret:argocd/github-token # AWSSecretsManagerClientReadOnlyAccessをIAM Roleにつけておくと、この参照ができる
IAM Roleを作成する模擬的なPulumi C#のコードは次のようになります。
var argoCDCapabilityRole = new IamRoleComponent($"{name}-capability-argocd", opt, new() { RequireInstanceProfile = false, AssumeRolePolicy = IamPolicy.GetAssumeRolePolicyJson("capabilities.eks.amazonaws.com", ["sts.AssumeRole", "sts:TagSession"]), IamPolicyArg = new IamPolicyArg { PolicyArns = IamPolicy.GetAwsManagedPolicyArns( [ "arn:aws:iam::aws:policy/AWSSecretsManagerClientReadOnlyAccess", ]), }, RoleName = $"{name}-capability-argocd", });
ArgoCD Capabilityを作成する
IAM Roleが用意できたらEKS Capabilityを作成します。ドキュメントにはAWS CLIでの手順が載っていますが、Identity Centerとの連携が必要なので正直コンソールでやる方が楽です。IaCサポートもまだないので、今回は雰囲気をつかむことも狙ってコンソールでやってみましょう。
まずはCapabilityのタブから、Create capabilityをクリックします。

Argo CDを選択します。

ArgoCD Capabilityの設定画面が表示されます。今回はクラスター名をautomode-clusterにしていることを踏まえてスクショと見比べてましょう。各項目は次の通りです。
- Capability Name: デフォルトで
クラスター名-argocd - Capability Role: 先ほど作成したIAM Roleを指定。AssumeRoleの信頼関係に
capabilities.eks.amazonaws.comが設定されていれば、ドロップダウンに表示される - ArgoCD endpoint access: PublicかPrivateを選択。今回はPublicを選択1
- Authentication access: AWS Identity Center(IdC)のユーザー/グループとArgoCDのロールマッピング設定。管理を簡単・単純化するためにも、IdCはグループを使ってマッピングするのがよいでしょう。今回は
Adminグループ:Adminロール、ViewOnlyグループ:Viewerロールでマッピング
Additional configuration and defaultsで、ArgoCDが管理するnamespaceを指定できますが、そのままがいいです。OSS版ArgoCDでもインストール先のnamespaceは一般的にargocdにするはずなので。AWS Capability版のArgoCDは、Applicationsの展開先Namespaceは1か所固定です。

確認画面が出るので、問題なければ作成しましょう。
作成後、Capabilitiesタブに戻り、作成したCapabilityのステータスがACTIVEになっていることを確認します。

また、クラスターでCRDを見るとArgoCDのカスタムリソースが取得できるはずです。(大事)
$ kubectl api-resources | grep argoproj.io applications app,apps argoproj.io/v1alpha1 true Application applicationsets appset,appsets argoproj.io/v1alpha1 true ApplicationSet appprojects appproj,appprojs argoproj.io/v1alpha1 true AppProject
CapabilityのArgoCDにアクセスする
EKSコンソールからCapabilityタブでArgoCDを選択して、詳細を表示します。Argo API endpointにあるURLから、ArgoCDのWeb UIにアクセスできます。

いつものArgoCDのSSOログイン画面が表示されるので、LOGIN VIA SSOをクリックしてIdentity Centerの認証でログインします。どうやらArgoCD内部の独自OIDC実装ではなくDexを使っているようで、OIDCのリフレッシュトークンを見ないバグはないようです。

Identity Centerでログインしているなら、スムーズにArgoCDのダッシュボードが表示されます。ログインしていない場合は、Identity Centerのログイン画面が表示されます。

動作しているArgoCDバージョンは、EKS Consoleの表示と同様に3.1.8+eks-1のようです。OSS版の3.1.8は2025/10/1リリースされているので、1か月遅れくらいでCapability版に反映されている感じですね。
クラスターの追加
やっていて罠がクラスター追加でした。
OSS版のArgoCDはインクラスターのKubernetesクラスターをデフォルトで追加します。しかし、CapabilityのArgoCDはクラスターが空っぽです。クラスター追加しましょう。

クラスターの追加は、argocd cliかSecretsがドキュメントで紹介されていますが、いざ追加しようとしてもどっちもスムーズにいきません。
ということで順番に見ていきましょう。
argocd cliでクラスターを追加する
argocd cliは、通常argocd loginでArgoCDのエンドポイントにログインします。しかし、CapabilityのArgoCDはargocd loginをサポートしていません。代わりの接続セットアップはドキュメントで次のようになっています。環境変数を使った暗黙の認証ですね。
# 暗黙の認証を設定する CLUSTER_NAME=my-cluster CAPABILITY_NAME="$CLUSTER_NAME-argocd" MYPROFILE="foobar" export ARGOCD_SERVER=$(aws eks describe-capability --cluster-name $CLUSTER_NAME --capability-name $CAPABILITY_NAME --query 'capability.configuration.argoCd.serverUrl' --output text --profile $MYPROFILE) export ARGOCD_AUTH_TOKEN="ArgoCD Web UIからAPIトークンを発行する" export ARGOCD_OPTS="--grpc-web" # 後段で使うEKSクラスターのARNを取得する CLUSTER_ARN=$(aws eks describe-cluster --name $CLUSTER_NAME --query 'cluster.arn' --output text --profile $MYPROFILE)
問題はこれでクラスターを追加しようとしても、うまくいきません。
$ argocd cluster add $CLUSTER_ARN --aws-cluster-name $CLUSTER_ARN --name in-cluster --project default {"level":"fatal","msg":"rpc error: code = Unknown desc = Post \"https://https//dummy01234567890.eks-capabilities.ap-northeast-1.amazonaws.com/cluster.ClusterService/Create\": dial tcp: lookup https on 10.255.255.254:53: read udp 10.255.255.254:45086-\u003e10.255.255.254:53: i/o timeout","time":"2025-12-03T18:47:21+09:00"} $ argocd cluster add $CLUSTER_ARN --aws-cluster-name $CLUSTER_ARN --name in-cluster --project default --insecure {"level":"fatal","msg":"rpc error: code = Unknown desc = Post \"https://https//dummy01234567890.eks-capabilities.ap-northeast-1.amazonaws.com/cluster.ClusterService/Create\": dial tcp: lookup https on 10.255.255.254:53: read udp 10.255.255.254:45086-\u003e10.255.255.254:53: i/o timeout","time":"2025-12-03T18:47:21+09:00"}
対処として、ARGOCD_SERVERは通常https://を省くので、これを省くとうまくいきます。罠すぎる。
$ ARGOCD_SERVER=$(aws eks describe-capability --cluster-name $CLUSTER_NAME --capability-name $CAPABILITY_NAME --query 'capability.configuration.argoCd.serverUrl' --output text --profile $MYPROFILE | sed 's/^https:\/\///') $ argocd cluster add $CLUSTER_ARN --aws-cluster-name $CLUSTER_ARN --name in-cluster --project default Cluster 'https://dummy01234567890.gr7.ap-northeast-1.eks.amazonaws.com' added


Secretsでクラスターを追加する
Secretsで追加する場合、次のようなSecretをargocd namespaceに作成します。これはドキュメント通りです。今回はプロジェクトを追加しないので、project: defaultにしています。もし、初めてArgoCDを触るなら、まずはおとなしくdefaultプロジェクトに追加するのがよいでしょう。
$ kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: in-cluster namespace: argocd labels: argocd.argoproj.io/secret-type: cluster stringData: name: in-cluster server: arn:aws:eks:ap-northeast-1:0123456789:cluster/my-cluster project: default EOF
ちなみにOSS版ArgoCDのように、https://kubernetes.default.svcのようなインクラスターのKubernetes APIエンドポイントを指定してもクラスターが追加されません。EKS Capability版では、EKSクラスターのARNを指定する必要があるようです。2
# 機能しない apiVersion: v1 kind: Secret metadata: name: in-cluster namespace: argocd labels: argocd.argoproj.io/secret-type: cluster stringData: name: in-cluster server: https://kubernetes.default.svc project: default
EKS Access Entryの権限を調整する
このままいざアプリケーションを追加するとすると、次のようなAPIアクセスエラーが発生します。エラーになるKubernetes APIは、その時々で変わるのですが基本的に何にもアクセスできない感じです。
Failed to load live state: failed to get cluster info for "arn:aws:eks:ap-northeast-1:0123456789:cluster/my-cluster": error synchronizing cache state : failed to sync cluster https://dummy01234567890.ap-northeast-1.prod.ccs.eks.aws.dev: failed to load initial state of resource CSINode.storage.k8s.io: failed to list resources: csinodes.storage.k8s.io is forbidden: User "arn:aws:sts::0123456789:assumed-role/my-eks-capability-argocd/aws-go-sdk-1764755848957927621" cannot list resource "csinodes" in API group "storage.k8s.io" at the cluster scope
原因は、EKS Access Entryに紐づけたAccess Policyの権限が不足しているためです。ドキュメントには、リモートクラスターの時だけAmazonEKSClusterAdminPolicyを紐づけるように書かれていますが、インクラスターでも必要なようです。恐らくCapabilityのバグ(あるいは何かおかしい)と予想していますが、いったん追加しましょう。
EKS ConsoleのAccess Entriesタブに移動します。ArgoCD Capabilityを追加すると、自動的にarn:aws:iam::0123456789:role/mycluster-eks-capability-argocdというEKS Access Entryが作成されています。これを見ると、AmazonEKSArgoCDClusterPolicy, AmazonEKSArgoCDPolicyの2ポリシーが紐づいています。

Attach policiesボタンをクリックして、AmazonEKSClusterAdminPolicyを追加しましょう。3

aws cliで調整してもいいでしょう。
aws eks associate-access-policy \ --cluster-name my-cluster \ --principal-arn arn:aws:iam::0123456789:role/mycluster-eks-capability-argocd \ --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \ --access-scope type=cluster
before

after

アプリケーションを追加する
お待ちかねのアプリケーション追加です。今回は、簡単のためパブリックなGitHubリポジトリにあるサンプルアプリケーションを追加することで、ArgoCDのリポジトリ登録を省略します。試しに私のリポジトリguitarrapc/argocd-labにあるアプリケーションを追加します。
$ kubectl apply -f - <<EOF apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: argocd-lab namespace: argocd spec: project: default source: repoURL: https://github.com/guitarrapc/argocd-lab.git targetRevision: main path: k8s/api destination: name: in-cluster # Rename to actual cluster name if needed namespace: argocd-lab syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true EOF
ここでもしAPIエラーが発生したら、EKS Access Entryの権限を見直しましょう。
問題なくアプリケーションが追加できれば、次のように表示されます。

$ kubectl get all -n argocd-lab NAME READY STATUS RESTARTS AGE pod/api-csharp-5c77f5d6-wwttt 1/1 Running 0 4m20s pod/api-go-6dc5c4c5ff-4tmdk 1/1 Running 0 4m20s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/api-csharp-svc ClusterIP 172.20.44.169 <none> 80/TCP 4m20s service/api-go-svc ClusterIP 172.20.207.24 <none> 80/TCP 4m20s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/api-csharp 1/1 1 1 4m20s deployment.apps/api-go 1/1 1 1 4m20s NAME DESIRED CURRENT READY AGE replicaset.apps/api-csharp-5c77f5d6 1 1 1 4m20s replicaset.apps/api-go-6dc5c4c5ff 1 1 1 4m20s
仮に、Kubernets上からGoのAPIサーバーDeploymentを削除しても、ArgoCDが自動的に復元してくれます。
$ kubectl delete deployment api-go -n argocd-lab deployment.apps "api-go" deleted

3秒ほどで復元されました。
$ kubectl get deploy -n argocd-lab NAME READY UP-TO-DATE AVAILABLE AGE api-csharp 1/1 1 1 5m15s api-go 1/1 1 1 34s

ポートフォワードでアクセスしてみましょう。
$ kubectl port-forward -n argocd-lab svc/api-csharp-svc 8080:80 $ curl http://localhost:8080/ {"machineName":"api-csharp-56f8866dcd-qkkhw","osDescription":"Ubuntu 24.04.3 LTS","processorCount":1,"usedMemoryInMB":5} $ kubectl port-forward -n argocd-lab svc/api-go-svc 8081:80 $ curl http://localhost:8081/ {"machineName":"api-go-64665c8c5f-2brsk","osDescription":"linux amd64","processorCount":2,"usedMemoryInMB":0}
削除もいつも通りです。アプリケーションを消してもいいですし、ArgoCD UIから削除してもOKです。

できないこと
OSS版ArgoCDを使っているため、ドキュメントで示されている「Capability版でできないこと」のいくつかが気になります。
ArgoCD Notificationsが使えない
ArgoCD Notificationsは、ArgoCDのイベントをSlackなどに通知する仕組みです。Capability版のArgoCDは、現状この機能をサポートしていません。
具体的には、ArgoCDはコントローラーの状態やNodeの状態によって、アプリケーションの同期状態が変わります。これをSlackなどに通知するときにArgoCD Notificationsを使います。Slack通知がないと見落としやすいため、使えないのはちょっと痛いです。
ArgoCD RBACはいじれない
OSS版ArgoCDは、ポリシーを定義することで自由にArgoCD内部RBACを設定できました。しかし、Capability版ではこの設定ができず、Admin、Editor、Viewerの3ロールに固定されています。細かい権限設定ができないのはちょっと困ります。
たとえば、Syncでデプロイはできるけど、リソースの直接削除・編集はさせたくない。などは調整できない感じですね。
IdentityCenter以外のSSO認証がない
OSS版ArgoCDは任意のOIDC認証を設定できるので、CognitoやAuth0、Okta、Azure EntraID、Google Workspaceなど認証バックエンドを自由に選択できます。Capability版は、現状Identity Centerに固定されています。Identity Centerは悪くないのですが、他の認証バックエンドを使いたい場合は困ります。
個人的にうへーって感じなので、割と深刻に困る人はいるんじゃないですかね。Identity CenterをIdPとして利用するのって、これまであまりなかったような気がします。
ApplicationのNamespaceが一つ
OSS版ArgoCDは複数のNamespaceにApplicatcionをデプロイできましたが、Capability版では1Namespaceに固定されています。デフォルトならargocdNamespaceです。運用回避が可能な範囲ですが、アプリケーションと一緒のnamespaceにデプロイしたい時は困るでしょう。
現状は制約ですが、将来改善予定のようです。
Argo CD Image Updaterが使えない
Argo CD Image Updaterは、コンテナイメージのバージョン更新を検知して、GitHubなどのマニフェストリポジトリに更新PRを自動で作成する仕組みです。これを前提にできるならCIはマニフェストの展開を考える必要がなくなり、イメージプッシュまでが責務になるので便利。ですが、Capability版ではこの機能がサポートされていません。
しょうがない。
無理やりPodを消せない
割と力づくなのでめったにやらないのですが、OSS版ArgoCDでは特定のArgoCDコントローラーを強制に停止させることで、Podを0台にしてランニングコストを下げることができます。しかし、Capability版ではCapabilityが設定されているだけで時間課金されるため、コストを強制的に下げるみたいな荒業は使えません。一長一短ですね。
あと、CRDがかかわっているのでCapability版のArgoCDをアンインストールする前に、Applicationを忘れず削除する必要があるなどは忘れそうで注意です。
コスト
ArgoCD Capabilityのコストは次の通りです。料金は英語ページにしかまだ載ってないようです。
アプリケーションが多いほどお金かかるのはArgoCD的の負荷的にはそうなんですが、OSS版ArgoCDで考えるとアプリケーションが1,2つ増えてもPod負荷は変わらないので、フーンってお気持ちです。10とかあると変わるんですけどね。とはいえ、維持費が$26.98992/month、アプリケーション5つが常時稼働で$6.6708/month、合計$33.66072/monthです。まあ、ArgoCDのPodを5台以上立てることを考えると妥当な気もします。4
- Argo CD base charge $0.037486 per Argo CD Capability hour (Capability自体の維持費)
- Argo CD usage charge $0.001853 per Argo CD Application hour (Applicationあたりの維持費)

TIPS
コンテキスト名を変えてargocd cliを使いたい
Kubernetes ContextでEKS Clusterの接続名を変えると、クラスター追加時のargocdコマンドが変わります。TIPSとしておいておきます。
例えば、コンテキスト名をarn形式arn:aws:eks....からクラスター名my-clusterにしたとしましょう。すると、argocd cliでクラスター追加時にコンテキスト名が一致せず失敗します。
$ kubectx ${CLUSTER_NAME}=arn:aws:eks:${REGION}:${ACCOUNT_ID}:cluster/${CLUSTER_NAME} $ argocd cluster add $CLUSTER_ARN --aws-cluster-name $CLUSTER_ARN --name in-cluster --project default {"level":"fatal","msg":"context arn:aws:eks:ap-northeast-1:012345689:cluster/my-cluster does not exist in kubeconfig","time":"2025-12-03T19:30:14+09:00"}
この場合、$CLUSTER_ARNの代わりに、コンテキストの名前${CLUSTER_NAME}を指定します。
$ argocd cluster add $CLUSTER_NAME --aws-cluster-name $CLUSTER_ARN --name in-cluster --project default Cluster 'https://dummy01234567890.gr7.ap-northeast-1.eks.amazonaws.com' added
まとめ
EKS CapabilityでArgoCDを展開してみました。現状でも十分に使えそうですが、いくつか気になる点もあります。特にEKS Access Entryの権限周りは、もう少し改善してほしいところです。
IaC側のサポートがないので、今のままだとCapabilityを追加しても、クラスターを消すときに連動しないので厄介です。Terraformは実装中で、Pulumi.Awsはこれが入ったら自動変換で入る想定なので、少し待ちましょう。
参考
- Amazon EKS の新機能発表:ワークロードオーケストレーションとクラウドリソース管理 | Amazon Web Services ブログ
- Comparing EKS Capability for Argo CD to self-managed Argo CD | Amazon EKS
- Create an Argo CD capability using the AWS CLI | Amazon EKS
- Register target clusters | Amazon EKS
- guitarrapc/argocd-lab | GitHub
- EKS Capabilities のご紹介 #AWS | Qiita
- これかなり微妙です。PublicだとPublicにログイン画面へ到達できるので、正直Privateがよいです。いくらIdentity Centerで認証してもPublicにログイン画面が出てしまうのは、想定外の状況で攻撃ベクターを不要に与えることになります。Privateにして、VPC Endpoint経由でアクセスするのがよいですが、正直IP制限かZero TrustなネットワークをAWSが提供してほしい。↩
- AWS側のコントローラーでarnフォーマットかチェックしてそう。↩
- これ、権限強すぎるし、原理的にもおかしいので、バグっぽいですがどうなんでしょう↩
- EKS、こういう時に地味にお金かかるって感じあるんですよね。常時動かなくても、Serverless的な感じで時々フックされて動いてくれればいいのに、と運用してて感じることがあります。ありませんか?↩