Skip to content

Commit 3af9258

Browse files
committed
Add blog post: Registering a Spoke Cluster to EKS ArgoCD Capability
1 parent f93f9ce commit 3af9258

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
title: "Registering a Spoke Cluster to EKS ArgoCD Capability"
3+
date: 2026-01-06T14:39:01+08:00
4+
draft: false
5+
description: "Learn how to register spoke clusters to Amazon EKS ArgoCD Capability for multi-cluster GitOps deployments"
6+
tags: ["kubernetes", "argocd", "eks", "gitops", "aws"]
7+
categories: ["DevOps"]
8+
author: "Shawn Zhang"
9+
showToc: true
10+
TocOpen: false
11+
hidemeta: false
12+
comments: false
13+
disableHLJS: false
14+
disableShare: false
15+
searchHidden: false
16+
cover:
17+
image: "https://d2908q01vomqb2.cloudfront.net/fe2ef495a1152561572949784c16bf23abb28057/2025/12/18/ArgoCD-EKS-Multi-Cluster.drawio.png"
18+
alt: "Hub-and-Spoke Architecture for EKS ArgoCD Capability"
19+
caption: "Source: AWS Containers Blog"
20+
relative: false
21+
hidden: false
22+
---
23+
24+
## Overview
25+
26+
[Amazon EKS Capabilities](https://docs.aws.amazon.com/eks/latest/userguide/capabilities.html) is a set of fully managed cluster features that accelerate developer velocity and offload the complexity of building and scaling with Kubernetes. Among these capabilities, the **ArgoCD Capability** provides a fully managed GitOps continuous deployment solution—eliminating the operational overhead of installing, maintaining, and scaling Argo CD controllers on your clusters.
27+
28+
[Argo CD](https://argo-cd.readthedocs.io/) is a declarative, GitOps continuous delivery tool for Kubernetes. It follows the GitOps pattern where Git repositories serve as the single source of truth for defining the desired application state. Argo CD continuously monitors these repositories and automatically syncs the cluster state to match the desired configuration.
29+
30+
With the EKS ArgoCD Capability, AWS handles scaling, upgrades, and inter-cluster communications, while providing native integrations with services like Amazon ECR, AWS Secrets Manager, and AWS CodeConnections.
31+
32+
### Hub-and-Spoke Architecture
33+
34+
A common deployment pattern is the **hub-and-spoke** topology: the ArgoCD Capability runs on a dedicated central EKS cluster (the hub) that serves as the control plane for GitOps operations, managing deployments to multiple workload clusters (spokes). This provides a single pane of glass to orchestrate deployments across clusters—whether they're in different regions, accounts, or have private API endpoints.
35+
36+
![Hub-and-Spoke Architecture for EKS ArgoCD Capability](https://d2908q01vomqb2.cloudfront.net/fe2ef495a1152561572949784c16bf23abb28057/2025/12/18/ArgoCD-EKS-Multi-Cluster.drawio.png)
37+
*Figure: Hub-and-spoke topology for EKS ArgoCD Capability (Source: [AWS Containers Blog](https://aws.amazon.com/blogs/containers/deep-dive-streamlining-gitops-with-amazon-eks-capability-for-argo-cd/))*
38+
39+
**This post focuses on registering a spoke cluster to an existing hub cluster with ArgoCD Capability enabled.**
40+
41+
## Prerequisites
42+
43+
- Hub cluster with ArgoCD Capability enabled
44+
- ArgoCD Capability IAM role ARN (e.g., `ArgoCDCapabilityRole`)
45+
- kubectl configured for hub cluster
46+
47+
## Step 1: Grant ArgoCD Access to Spoke Cluster
48+
49+
Create an access entry and associate cluster admin policy on the spoke cluster:
50+
51+
```bash
52+
# Create access entry
53+
aws eks create-access-entry \
54+
--cluster-name <spoke-cluster> \
55+
--region <region> \
56+
--principal-arn arn:aws:iam::<account-id>:role/ArgoCDCapabilityRole
57+
58+
# Associate cluster admin policy
59+
aws eks associate-access-policy \
60+
--cluster-name <spoke-cluster> \
61+
--region <region> \
62+
--principal-arn arn:aws:iam::<account-id>:role/ArgoCDCapabilityRole \
63+
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \
64+
--access-scope type=cluster
65+
```
66+
67+
## Step 2: Create ArgoCD Project
68+
69+
Create a dedicated project for spoke workloads (skip if already exists):
70+
71+
```yaml
72+
apiVersion: argoproj.io/v1alpha1
73+
kind: AppProject
74+
metadata:
75+
name: spoke-workloads
76+
namespace: argocd
77+
spec:
78+
destinations:
79+
- namespace: '*'
80+
name: <spoke-cluster> # Add each spoke cluster
81+
sourceRepos:
82+
- '*'
83+
clusterResourceWhitelist:
84+
- group: '*'
85+
kind: '*'
86+
sourceNamespaces:
87+
- argocd # Required for apps in argocd namespace
88+
```
89+
90+
To add more clusters to an existing project:
91+
92+
```bash
93+
kubectl patch appproject spoke-workloads -n argocd --type=json \
94+
-p='[{"op": "add", "path": "/spec/destinations/-", "value": {"namespace": "*", "name": "<new-spoke-cluster>"}}]'
95+
```
96+
97+
## Step 3: Register Cluster via Secret
98+
99+
Create a Kubernetes secret to register the spoke cluster:
100+
101+
```yaml
102+
apiVersion: v1
103+
kind: Secret
104+
metadata:
105+
name: <spoke-cluster>
106+
namespace: argocd
107+
labels:
108+
argocd.argoproj.io/secret-type: cluster
109+
environment: dev # Optional: for ApplicationSet selectors
110+
annotations:
111+
region: <region> # Optional: metadata
112+
stringData:
113+
name: <spoke-cluster>
114+
server: arn:aws:eks:<region>:<account-id>:cluster/<spoke-cluster>
115+
project: spoke-workloads
116+
```
117+
118+
> **Important**: The `server` field must be the EKS cluster ARN, not the Kubernetes API URL or IAM role ARN.
119+
120+
## Step 4: Deploy Application
121+
122+
Create an ArgoCD Application targeting the spoke cluster:
123+
124+
```yaml
125+
apiVersion: argoproj.io/v1alpha1
126+
kind: Application
127+
metadata:
128+
name: my-app
129+
namespace: argocd
130+
spec:
131+
project: spoke-workloads
132+
source:
133+
repoURL: https://github.com/org/repo
134+
targetRevision: HEAD
135+
path: .
136+
destination:
137+
name: <spoke-cluster> # Matches the secret name
138+
namespace: default
139+
syncPolicy:
140+
automated:
141+
prune: true
142+
selfHeal: true
143+
syncOptions:
144+
- CreateNamespace=true
145+
```
146+
147+
## Quick Reference
148+
149+
| Field | Value | Note |
150+
|-------|-------|------|
151+
| `server` in Secret | EKS cluster ARN | `arn:aws:eks:<region>:<account>:cluster/<name>` |
152+
| `destination.name` | Cluster secret name | Not the server URL |
153+
| `sourceNamespaces` | `argocd` | Required in AppProject |
154+
155+
## Troubleshooting
156+
157+
### Application stuck in Unknown status
158+
159+
Check if the project allows the application:
160+
161+
```bash
162+
kubectl get application <app-name> -n argocd -o jsonpath='{.status.conditions[*].message}'
163+
```
164+
165+
If you see "not permitted to use project", ensure `sourceNamespaces: [argocd]` is set in the AppProject.
166+
167+
### Cluster not reachable
168+
169+
Verify access entry exists:
170+
171+
```bash
172+
aws eks list-access-entries --cluster-name <spoke-cluster> --region <region>
173+
```
174+
175+
Verify access policy is associated:
176+
177+
```bash
178+
aws eks list-associated-access-policies \
179+
--cluster-name <spoke-cluster> \
180+
--region <region> \
181+
--principal-arn arn:aws:iam::<account-id>:role/ArgoCDCapabilityRole
182+
```
183+
184+
### Force refresh application
185+
186+
```bash
187+
kubectl patch application <app-name> -n argocd --type merge \
188+
-p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
189+
```
190+

0 commit comments

Comments
 (0)