Amazon EKS — ArgoCD on EKS
ArgoCD is the most popular GitOps tool for Kubernetes. It watches a Git repository and continuously reconciles the desired state (manifests in Git) with the actual state (what’s running in the cluster).
Install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Wait for pods
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s
Get Initial Admin Password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
Install ArgoCD CLI
brew install argocd
argocd login localhost:8080 --username admin --password <password> --insecure
ALB Ingress for ArgoCD UI
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server
namespace: argocd
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:123456789012:certificate/abc-123
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/backend-protocol: HTTPS
alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
ingressClassName: alb
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 443
Application CRD
Define an ArgoCD Application to manage a workload:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/my-org/k8s-manifests.git
targetRevision: main
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # Delete resources removed from Git
selfHeal: true # Revert manual changes in cluster
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
maxDuration: 3m0s
factor: 2
Key sync options:
| Option | Description |
|---|---|
automated.prune |
Delete resources not in Git |
automated.selfHeal |
Override manual changes in cluster |
CreateNamespace=true |
Create target namespace if missing |
ServerSideApply=true |
Use server-side apply (avoids annotation limits) |
ApplicationSet for Multi-Environment
Deploy the same app across multiple clusters or environments:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-app
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: staging
url: https://staging-cluster-api.example.com
namespace: staging
- cluster: production
url: https://prod-cluster-api.example.com
namespace: production
template:
metadata:
name: "my-app-"
spec:
project: default
source:
repoURL: https://github.com/my-org/k8s-manifests.git
targetRevision: main
path: "apps/my-app/overlays/"
destination:
server: ""
namespace: ""
syncPolicy:
automated:
prune: true
selfHeal: true
Multi-Cluster Management
Register external clusters:
# Add staging cluster
argocd cluster add staging-cluster-context --name staging
# Add production cluster
argocd cluster add production-cluster-context --name production
# List registered clusters
argocd cluster list
SSO with AWS Cognito
Configure ArgoCD to use Cognito for authentication:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Cognito
issuer: https://cognito-idp.us-east-1.amazonaws.com/<user-pool-id>
clientID: <client-id>
clientSecret: $oidc.cognito.clientSecret
requestedScopes:
- openid
- profile
- email
RBAC policy:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
g, platform-team, role:admin
g, dev-team, role:readonly
policy.default: role:readonly
ArgoCD Image Updater
Automatically update image tags in Git when new images are pushed to ECR:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Annotate your Application:
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: my-app=123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app
argocd-image-updater.argoproj.io/my-app.update-strategy: semver
argocd-image-updater.argoproj.io/my-app.allow-tags: "regexp:^v[0-9]+\\.[0-9]+\\.[0-9]+$"
argocd-image-updater.argoproj.io/write-back-method: git
Best Practices
- Enable auto-sync with prune and selfHeal — ensures Git is always the source of truth
- Use ApplicationSets for multi-env/multi-cluster — DRY configuration
- Store ArgoCD Applications in Git (app of apps pattern) — manage ArgoCD with ArgoCD
- Configure SSO — don’t use the admin password in production
- Use Image Updater — automate image tag updates without manual Git commits
- Separate infra and app repos — platform team manages infra, dev teams manage app manifests