| name | argocd-gitops |
| description | Implement GitOps with ArgoCD for declarative Kubernetes deployments. Configure applications, manage sync policies, implement progressive delivery, and automate deployments from Git repositories. Use when implementing GitOps workflows or continuous deployment to Kubernetes. |
| license | MIT |
| metadata | {"author":"devops-skills","version":"1.0"} |
ArgoCD GitOps
Implement declarative continuous delivery for Kubernetes with ArgoCD.
When to Use This Skill
Use this skill when:
- Implementing GitOps workflows for Kubernetes
- Automating deployments from Git repositories
- Managing multiple environments declaratively
- Implementing progressive delivery strategies
- Synchronizing cluster state with Git
Prerequisites
- Kubernetes cluster with ArgoCD installed
- kubectl configured
- Git repository for manifests
- ArgoCD CLI (optional)
Installation
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/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
Application Definition
Basic Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/myapp-manifests.git
targetRevision: main
path: environments/production
destination:
server: https://kubernetes.default.svc
namespace: myapp
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Helm Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-helm
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/myapp-chart.git
targetRevision: main
path: charts/myapp
helm:
valueFiles:
- values.yaml
- values-production.yaml
parameters:
- name: replicaCount
value: "3"
- name: image.tag
value: "2.0.0"
destination:
server: https://kubernetes.default.svc
namespace: myapp
syncPolicy:
automated:
prune: true
selfHeal: true
Kustomize Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-kustomize
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/myapp-manifests.git
targetRevision: main
path: overlays/production
kustomize:
images:
- myapp=myregistry/myapp:2.0.0
destination:
server: https://kubernetes.default.svc
namespace: myapp
Projects
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: myproject
namespace: argocd
spec:
description: My Project
sourceRepos:
- https://github.com/org/*
destinations:
- namespace: myapp-*
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceWhitelist:
- group: '*'
kind: '*'
roles:
- name: developer
description: Developer role
policies:
- p, proj:myproject:developer, applications, get, myproject/*, allow
- p, proj:myproject:developer, applications, sync, myproject/*,
Application Sets
Git Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-environments
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/org/myapp-manifests.git
revision: main
directories:
- path: environments/*
template:
metadata:
name: 'myapp-{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp-manifests.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: 'myapp-{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
List Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-clusters
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: production
url: https://prod-cluster.example.com
- cluster: staging
url: https://staging-cluster.example.com
template:
metadata:
name: 'myapp-{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp-manifests.git
targetRevision: main
path: 'environments/{{cluster}}'
destination:
server: '{{url}}'
namespace: myapp
Matrix Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-matrix
namespace: argocd
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/org/myapp-manifests.git
revision: main
directories:
- path: apps/*
- list:
elements:
- env: staging
- env: production
template:
metadata:
name: '{{path.basename}}-{{env}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp-manifests.git
targetRevision: main
path: '{{path}}/overlays/{{env}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}-{{env}}'
Sync Policies
Automated Sync
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Sync Waves
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfig
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
argocd.argoproj.io/sync-wave: "0"
Sync Hooks
apiVersion: batch/v1
kind: Job
metadata:
name: migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["./migrate.sh"]
restartPolicy: Never
CLI Commands
argocd app list
argocd app get myapp
argocd app sync myapp
argocd app sync myapp --force
argocd app diff myapp
argocd app rollback myapp
argocd app delete myapp
argocd app logs myapp
argocd app get myapp --hard-refresh
Repository Configuration
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
url: https://github.com/org/private-repo.git
username: git
password: ghp_xxxx
---
apiVersion: v1
kind: Secret
metadata:
name: private-repo-ssh
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
url: git@github.com:org/private-repo.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Notifications
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-deployed: |
message: Application {{.app.metadata.name}} is now {{.app.status.sync.status}}.
trigger.on-deployed: |
- when: app.status.operationState.phase in ['Succeeded']
send: [app-deployed]
Common Issues
Issue: Sync Fails with Diff
Problem: Resources show differences but are correct
Solution: Configure ignore differences
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
Issue: Repository Not Accessible
Problem: ArgoCD cannot clone repository
Solution: Check repository secret, verify URL and credentials
Issue: Application Stuck OutOfSync
Problem: Application never becomes synced
Solution: Check resource status, review events, verify manifests
Issue: Health Check Failing
Problem: Application shows degraded health
Solution: Check custom health checks, verify probe configurations
Best Practices
- Use ApplicationSets for multi-environment deployments
- Implement sync waves for ordered deployments
- Use projects to isolate applications
- Configure notifications for deployment events
- Implement proper RBAC with projects
- Use health checks for deployment verification
- Enable auto-pruning to remove deleted resources
- Keep manifests in dedicated repositories
Related Skills