ArgoCD GitOps in Practice: App Sync, Multi-Cluster Management, ApplicationSet, and Rollout Strategies
GitOps treats your Git repository as the single source of truth for cluster state. ArgoCD continuously compares the desired state in Git with the live state in Kubernetes and reconciles any drift. This guide covers production ArgoCD patterns from basic Application resources to multi-cluster ApplicationSets and progressive delivery with Argo Rollouts.
Core Concepts
- Application maps a Git path to a Kubernetes cluster/namespace
- AppProject defines RBAC scope with allowed repos, clusters, and resource kinds
- ApplicationSet generates multiple Applications from a template
- Argo Rollouts is a progressive delivery controller for canary and blue/green deployments
Installation
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl rollout status deploy/argocd-server -n argocd
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
argocd login argocd.example.com --grpc-web
Application Resource
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-api
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: production
source:
repoURL: https://github.com/my-org/k8s-manifests
targetRevision: main
path: apps/my-api/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
AppProject: RBAC Boundaries
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: Production workloads
sourceRepos:
- 'https://github.com/my-org/*'
destinations:
- namespace: 'production'
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceWhitelist:
- group: 'apps'
kind: Deployment
- group: 'apps'
kind: StatefulSet
roles:
- name: developer
description: Can sync but not delete
policies:
- p, proj:production:developer, applications, get, production/*, allow
- p, proj:production:developer, applications, sync, production/*, allow
groups:
- my-org:developers
ApplicationSet: Generating Applications at Scale
List Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: microservices
namespace: argocd
spec:
generators:
- list:
elements:
- service: api
namespace: production
replicas: "3"
- service: worker
namespace: production
replicas: "5"
template:
metadata:
name: '{{service}}'
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/my-org/k8s-manifests
targetRevision: main
path: 'apps/{{service}}'
helm:
parameters:
- name: replicaCount
value: '{{replicas}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
Git Generator: Auto-Discovery
generators:
- git:
repoURL: https://github.com/my-org/k8s-manifests
revision: main
directories:
- path: 'apps/*/overlays/production'
Matrix Generator: Services x Environments
generators:
- matrix:
generators:
- list:
elements:
- env: staging
cluster: https://staging-cluster.example.com
- env: production
cluster: https://prod-cluster.example.com
- git:
repoURL: https://github.com/my-org/k8s-manifests
revision: main
directories:
- path: 'apps/*'
Pull Request Generator for Preview Environments
generators:
- pullRequest:
github:
owner: my-org
repo: my-app
tokenRef:
secretName: github-token
key: token
labels:
- preview
requeueAfterSeconds: 60
template:
metadata:
name: 'preview-{{number}}'
spec:
source:
path: apps/my-app
helm:
parameters:
- name: image.tag
value: 'pr-{{number}}'
destination:
namespace: 'preview-{{number}}'
Multi-Cluster Management
Register External Cluster
argocd cluster add prod-cluster-west --name prod-west
argocd cluster list
ApplicationSet with Cluster Generator
generators:
- clusters:
selector:
matchLabels:
argocd.argoproj.io/secret-type: cluster
environment: production
template:
spec:
destination:
server: '{{server}}'
namespace: production
Argo Rollouts: Progressive Delivery
Canary Rollout
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-api
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- analysis:
templates:
- templateName: error-rate-check
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100
canaryService: my-api-canary
stableService: my-api-stable
trafficRouting:
nginx:
stableIngress: my-api-ingress
AnalysisTemplate for Automated Promotion
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: error-rate-check
spec:
metrics:
- name: error-rate
interval: 1m
count: 5
successCondition: result[0] < 0.01
failureLimit: 1
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{status=~"5..",rollout_type="canary"}[5m]))
/
sum(rate(http_requests_total{rollout_type="canary"}[5m]))
Image Updater
kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=registry.example.com/my-app
argocd-image-updater.argoproj.io/myapp.update-strategy: semver
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main
Conclusion
ArgoCD transforms Kubernetes operations from imperative kubectl commands to declarative Git-driven workflows. ApplicationSets eliminate toil when managing dozens of services or clusters. Argo Rollouts add traffic-weighted canary deployments with automated analysis. Together they form a complete GitOps platform that gives teams velocity and safety when deploying to production.