Argo CD
CI/CD Tool
Argo CD
Overview
Argo CD is a declarative GitOps continuous delivery tool for Kubernetes. It monitors Git repository configuration changes and automatically executes deployments to Kubernetes clusters, enabling modern cloud-native operations.
Details
Argo CD is a declarative continuous delivery tool that implements GitOps methodology in Kubernetes environments, serving as a graduated project of the Cloud Native Computing Foundation (CNCF). In 2024-2025, ApplicationSet enhancements have significantly improved multi-application and multi-cluster management, accelerating adoption in large enterprises. Following core GitOps principles, it makes application definitions, configurations, and environments declarative and version-controlled, while automating deployment and lifecycle management in an auditable and understandable manner. When changes occur in Kubernetes configurations (manifest files) in Git, Argo CD notifies users and prompts synchronization with the desired state. When configuration drift occurs in production systems, Argo CD detects changes and automatically restores to the desired state defined in Git. Extending beyond Argo CD Application resources that deploy from a single Git repository to a single cluster/namespace, ApplicationSet uses template-based automation to create, modify, and manage multiple Argo CD applications simultaneously. It supports configuration management and templating tools including YAML, Helm charts, Jsonnet, and Kustomize, and can implement Canary and Blue-Green deployment strategies combined with Argo Rollouts. Integration with SSO providers including OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, and LinkedIn provides enterprise-level security and multi-tenancy.
Pros and Cons
Pros
- Declarative GitOps: Git as source of truth for configuration management and auto-sync
- Full Kubernetes Integration: K8s-native configuration and CRD support
- ApplicationSet: Centralized management of multiple apps across clusters
- Visual UI: Intuitive web UI for deployment status monitoring
- Auto-Recovery: Configuration drift detection and automatic desired state restoration
- Multi-tenancy: Project-based permission and resource isolation
- Rich Integrations: Support for Helm, Kustomize, Jsonnet
- SSO Support: Enterprise authentication system integration
- Rollback Capabilities: Easy previous version recovery via Git history
Cons
- Kubernetes-Only: No support for other platforms
- Learning Curve: Requires GitOps concepts and Kubernetes knowledge
- Git Dependency: Deployment impact during Git outages
- Configuration Complexity: ApplicationSet management in large environments
- Real-time Limitations: Sync delays due to polling intervals
- Debugging Difficulty: Complex manifest issue identification challenges
- Permission Management: Operational overhead of granular RBAC configuration
Key Links
- Argo CD Official Site
- Argo CD GitHub Repository
- Argo CD Installation Guide
- ApplicationSet Documentation
- Argo Project
- CNCF Argo CD
Code Examples
Basic Argo CD Installation
# Create Argo CD namespace
kubectl create namespace argocd
# Install Argo CD stable version
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Expose service (LoadBalancer)
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
# Get initial password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
# Install Argo CD CLI
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64
# CLI login
argocd login <ARGOCD_SERVER>
Basic Application Resource Definition
# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
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:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Multi-Application Management with ApplicationSet
# applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- clusters:
selector:
matchLabels:
argocd.argoproj.io/secret-type: cluster
- git:
repoURL: https://github.com/example/cluster-addons.git
revision: HEAD
directories:
- path: "cluster-addons/*"
template:
metadata:
name: '{{.path.basename}}-{{.name}}'
spec:
project: default
source:
repoURL: https://github.com/example/cluster-addons.git
targetRevision: HEAD
path: '{{.path.path}}'
destination:
server: '{{.server}}'
namespace: '{{.path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Helm Chart Integration and Values File Management
# helm-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prometheus
namespace: argocd
spec:
project: default
source:
repoURL: https://prometheus-community.github.io/helm-charts
chart: prometheus
targetRevision: 25.27.0
helm:
valueFiles:
- values-production.yaml
parameters:
- name: server.persistentVolume.size
value: 100Gi
- name: server.replicaCount
value: "2"
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Kustomize Integration and Overlay Management
# kustomize-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: webapp-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/webapp-config.git
targetRevision: HEAD
path: overlays/production
kustomize:
images:
- webapp:v1.2.3
patches:
- target:
kind: Deployment
name: webapp
patch: |-
- op: replace
path: /spec/replicas
value: 5
destination:
server: https://kubernetes.default.svc
namespace: webapp-prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- RespectIgnoreDifferences=true
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
Environment × Cluster Deployment with Matrix Generator
# matrix-applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: webapp-environments
namespace: argocd
spec:
goTemplate: true
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/example/app-config.git
revision: HEAD
files:
- path: "environments/*/config.json"
- clusters:
selector:
matchLabels:
environment: '{{.path.basename}}'
template:
metadata:
name: 'webapp-{{.path.basename}}-{{.name}}'
spec:
project: default
source:
repoURL: https://github.com/example/webapp.git
targetRevision: HEAD
path: k8s
kustomize:
images:
- webapp:{{.config.image.tag}}
destination:
server: '{{.server}}'
namespace: webapp-{{.path.basename}}
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Progressive Rollout Strategy
# progressive-rollout-applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: webapp-rollout
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: dev-cluster
env: dev
priority: "1"
- cluster: staging-cluster
env: staging
priority: "2"
- cluster: prod-us-west
env: production
priority: "3"
- cluster: prod-eu-west
env: production
priority: "3"
- cluster: prod-asia
env: production
priority: "4"
strategy:
type: RollingUpdate
rollingUpdate:
steps:
- matchExpressions:
- key: priority
operator: In
values: ["1"]
maxUpdate: 0 # Update all simultaneously
- matchExpressions:
- key: priority
operator: In
values: ["2"]
maxUpdate: 1 # Update one by one
- matchExpressions:
- key: priority
operator: In
values: ["3"]
maxUpdate: 50% # Update 50% at a time
- matchExpressions:
- key: priority
operator: In
values: ["4"]
template:
metadata:
name: 'webapp-{{.cluster}}'
labels:
env: "{{.env}}"
priority: "{{.priority}}"
spec:
project: default
source:
repoURL: https://github.com/example/webapp.git
targetRevision: HEAD
path: k8s/{{.env}}
destination:
server: '{{.cluster}}'
namespace: webapp
syncPolicy:
automated:
prune: true
selfHeal: true
Private Repository and Secret Management
# private-repo-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/company/private-repo.git
username: deployment-bot
password: $GITHUB_TOKEN
project: webapp-project
---
# cluster-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mycluster-secret
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
stringData:
name: production-cluster
server: https://production-k8s.company.com
config: |
{
"bearerToken": "$CLUSTER_TOKEN",
"tlsClientConfig": {
"insecure": false,
"caData": "$CA_DATA"
}
}
---
# app-project.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: webapp-project
namespace: argocd
spec:
description: "Web Application Project"
sourceRepos:
- 'https://github.com/company/*'
- 'https://helm-charts.company.com/*'
destinations:
- namespace: 'webapp-*'
server: '*'
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceWhitelist:
- group: apps
kind: Deployment
- group: ''
kind: Service
- group: ''
kind: ConfigMap
- group: ''
kind: Secret
roles:
- name: webapp-admin
description: Admin access to webapp project
policies:
- p, proj:webapp-project:webapp-admin, applications, *, webapp-project/*, allow
- p, proj:webapp-project:webapp-admin, repositories, *, *, allow
groups:
- company:webapp-team