--- 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 ```bash # Create namespace kubectl create namespace argocd # Install ArgoCD kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml # Get admin password kubectl -n argocd get secret argocd-initial-admin-secret \ -o jsonpath="{.data.password}" | base64 -d # Port forward to access UI kubectl port-forward svc/argocd-server -n argocd 8080:443 # Login with CLI argocd login localhost:8080 ``` ## Application Definition ### Basic Application ```yaml 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 ```yaml 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 ```yaml 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 ```yaml 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/*, allow groups: - developers ``` ## Application Sets ### Git Generator ```yaml 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 ```yaml 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 ```yaml 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 ```yaml syncPolicy: automated: prune: true # Delete resources not in Git selfHeal: true # Revert manual changes allowEmpty: false # Don't sync empty directories syncOptions: - CreateNamespace=true - PrunePropagationPolicy=foreground - PruneLast=true retry: limit: 5 backoff: duration: 5s factor: 2 maxDuration: 3m ``` ### Sync Waves ```yaml # In Kubernetes manifests apiVersion: v1 kind: ConfigMap metadata: name: myconfig annotations: argocd.argoproj.io/sync-wave: "-1" # Sync first --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp annotations: argocd.argoproj.io/sync-wave: "0" # Sync second ``` ### Sync Hooks ```yaml 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 ```bash # List applications argocd app list # Get application details argocd app get myapp # Sync application argocd app sync myapp # Force sync (ignore differences) argocd app sync myapp --force # View diff argocd app diff myapp # Rollback argocd app rollback myapp # Delete application argocd app delete myapp # View logs argocd app logs myapp # Hard refresh (clear cache) argocd app get myapp --hard-refresh ``` ## Repository Configuration ```yaml 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 --- # SSH key 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 ```yaml 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 ```yaml 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 - [kubernetes-ops](../kubernetes-ops/) - K8s fundamentals - [helm-charts](../helm-charts/) - Helm deployments - [kustomize](../kustomize/) - Kustomize overlays