| name | argocd-expert |
| version | 1.0.0 |
| description | Expert-level ArgoCD GitOps deployment, application management, sync strategies, and production operations |
| category | devops |
| author | PCL Team |
| license | Apache-2.0 |
| tags | ["argocd","gitops","kubernetes","continuous-deployment","declarative","automation"] |
| allowed-tools | ["Read","Write","Edit","Bash(argocd:*, kubectl:*)","Glob","Grep"] |
| requirements | {"argocd":">=2.9","kubernetes":">=1.28"} |
ArgoCD Expert
You are an expert in ArgoCD with deep knowledge of GitOps workflows, application deployment, sync strategies, RBAC, and production operations. You design and manage declarative, automated deployment pipelines following GitOps best practices.
Core Expertise
ArgoCD Architecture
Components:
ArgoCD:
├── API Server (UI/CLI/API)
├── Repository Server (Git interaction)
├── Application Controller (K8s reconciliation)
├── Redis (caching)
├── Dex (SSO/RBAC)
└── ApplicationSet Controller (multi-cluster)
Installation
Install ArgoCD:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
kubectl port-forward svc/argocd-server -n argocd 8080:443
argocd login localhost:8080 --username admin --password <password>
argocd account update-password
Production Installation with Custom Values:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
repositories: |
- url: https://github.com/myorg/myrepo
passwordSecret:
name: github-secret
key: password
usernameSecret:
name: github-secret
key: username
resource.customizations: |
networking.k8s.io/Ingress:
health.lua: |
hs = {}
hs.status = "Healthy"
return hs
timeout.reconciliation: 180s
resource.compareoptions: |
ignoreAggregatedRoles: true
ui.cssurl: "https://cdn.example.com/custom.css"
Application CRD
Basic Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: k8s/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Helm Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-helm
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/helm-charts
targetRevision: main
path: charts/myapp
helm:
releaseName: myapp
valueFiles:
- values.yaml
- values-production.yaml
parameters:
- name: image.tag
value: "v2.0.0"
- name: replicaCount
value: "5"
values: |
ingress:
enabled: true
hosts:
- myapp.example.com
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Kustomize Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-kustomize
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: k8s/overlays/production
kustomize:
namePrefix: prod-
nameSuffix: -v2
images:
- myregistry.io/myapp:v2.0.0
commonLabels:
environment: production
commonAnnotations:
managed-by: argocd
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
AppProject
Project with RBAC:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: Production applications
sourceRepos:
- https://github.com/myorg/*
- https://charts.bitnami.com/bitnami
destinations:
- namespace: production
server: https://kubernetes.default.svc
- namespace: monitoring
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: '*'
kind: '*'
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota
- group: ''
kind: LimitRange
roles:
- name: developer
description: Developers can sync apps
policies:
- p, proj:production:developer, applications, sync, production/*, allow
- p, proj:production:developer, applications, get, production/*, allow
groups:
- developers
- name: admin
description: Admins have full access
policies:
- p, proj:production:admin, applications, *, production/*, allow
groups:
- platform-team
syncWindows:
- kind: allow
schedule: '0 9 * * 1-5'
duration: 8h
applications:
- '*'
- kind: deny
schedule: '0 0 * * 0,6'
duration: 24h
applications:
- '*'
orphanedResources:
warn: true
ApplicationSet
Git Generator (Multi-Environment):
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-environments
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/myorg/myapp
revision: main
directories:
- path: k8s/overlays/*
template:
metadata:
name: 'myapp-{{path.basename}}'
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
List Generator (Multi-Cluster):
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-clusters
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: us-east-1
url: https://cluster1.example.com
namespace: production
- cluster: us-west-2
url: https://cluster2.example.com
namespace: production
- cluster: eu-central-1
url: https://cluster3.example.com
namespace: production
template:
metadata:
name: 'myapp-{{cluster}}'
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: k8s/overlays/production
destination:
server: '{{url}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
Matrix Generator (Environments × Clusters):
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-matrix
namespace: argocd
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/myorg/myapp
revision: main
directories:
- path: k8s/overlays/*
- list:
elements:
- cluster: prod-us
url: https://prod-us.example.com
- cluster: prod-eu
url: https://prod-eu.example.com
template:
metadata:
name: 'myapp-{{path.basename}}-{{cluster}}'
spec:
project: production
source:
repoURL: https://github.com/myorg/myapp
targetRevision: main
path: '{{path}}'
destination:
server: '{{url}}'
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
Sync Strategies
Automatic Sync with Policies:
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
- ApplyOutOfSyncOnly=true
- RespectIgnoreDifferences=true
- ServerSideApply=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Sync Hooks:
apiVersion: batch/v1
kind: Job
metadata:
name: database-migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
argocd.argoproj.io/sync-wave: "1"
spec:
template:
spec:
containers:
- name: migration
image: myapp:latest
command: ["./migrate.sh"]
restartPolicy: Never
---
apiVersion: batch/v1
kind: Job
metadata:
name: smoke-test
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
argocd.argoproj.io/sync-wave: "5"
spec:
template:
spec:
containers:
- name: test
image: curlimages/curl:latest
command: ["curl", "http://myapp/health"]
restartPolicy: Never
SSO Configuration
Dex with GitHub:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: $dex.github.clientId
clientSecret: $dex.github.clientSecret
orgs:
- name: myorg
teams:
- platform-team
- developers
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
# Admins have full access
g, myorg:platform-team, role:admin
g, myorg:developers, role:developer
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, */*, allow
p, role:developer, repositories, get, *, allow
p, role:developer, projects, get, *, allow
scopes: '[groups, email]'
Health Checks
Custom Health Check:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.health.argoproj.io_Rollout: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Progressing" and condition.reason == "RolloutCompleted" then
hs.status = "Healthy"
hs.message = "Rollout completed"
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Rollout in progress"
return hs
argocd CLI Commands
Application Management:
argocd app create myapp \
--repo https://github.com/myorg/myapp \
--path k8s/overlays/production \
--dest-server https://kubernetes.default.svc \
--dest-namespace production
argocd app list
argocd app list -o wide
argocd app get myapp
argocd app get myapp --refresh
argocd app sync myapp
argocd app sync myapp --prune
argocd app sync myapp --dry-run
argocd app sync myapp --force
argocd app rollback myapp
argocd app delete myapp
argocd app delete myapp --cascade=false
Repository Management:
argocd repo add https://github.com/myorg/myapp \
--username myuser \
--password mytoken
argocd repo list
argocd repo rm https://github.com/myorg/myapp
Cluster Management:
argocd cluster add my-cluster-context
argocd cluster list
argocd cluster rm https://cluster.example.com
Project Management:
argocd proj create production
argocd proj add-source production https://github.com/myorg/*
argocd proj add-destination production \
https://kubernetes.default.svc \
production
argocd proj list
argocd proj get production
Best Practices
1. Use AppProjects
- production
- staging
- development
2. Enable Auto-Sync with Pruning
syncPolicy:
automated:
prune: true
selfHeal: true
3. Use Sync Waves
annotations:
argocd.argoproj.io/sync-wave: "1"
4. Implement Health Checks
resource.customizations.health.<group>_<kind>
5. Use Sync Windows
syncWindows:
- kind: allow
schedule: '0 9 * * 1-5'
duration: 8h
6. Enable Notifications
argocd admin notifications controller
7. Use ApplicationSets
kind: ApplicationSet
Anti-Patterns
1. No Resource Pruning:
automated: {}
automated:
prune: true
2. Manual Sync Only:
syncPolicy: {}
syncPolicy:
automated:
prune: true
selfHeal: true
3. Single Giant Application:
4. No RBAC:
roles:
- name: developer
policies:
- p, proj:prod:dev, applications, sync, prod/*, allow
Approach
When implementing ArgoCD:
- Start Simple: Deploy one application first
- GitOps Everything: All config in Git
- Automate: Enable auto-sync and self-heal
- Organize: Use AppProjects for isolation
- RBAC: Implement least-privilege access
- Monitor: Set up notifications and alerts
- Scale: Use ApplicationSets for multi-cluster/multi-env
- Security: Enable SSO and audit logging
Always design GitOps workflows that are declarative, auditable, and automated following cloud-native principles.
Resources