TL;DR

ArgoCD continuously compares desired state in Git with live cluster state. Healthy + Synced means live resources match Git and pass health checks. Find the owning Application before changing workloads — patch Git, not the cluster.

Mental Model

ConceptMeaning
ApplicationMaps a Git source to a Kubernetes destination
AppProjectRBAC boundary — which repos, clusters, and namespaces an app can use
SyncApply Git-rendered manifests to the cluster
HealthArgoCD's readiness interpretation per resource type
DriftLive state differs from Git-rendered desired state

Sync & Health Status

StatusMeaningFirst check
Synced / HealthyGit matches cluster; resources readyNo action needed
OutOfSyncLive differs from Gitargocd app diff
DegradedResource exists but unhealthykubectl describe the failing resource
MissingExpected resource not in clusterCheck prune history or manual deletion
UnknownHealth cannot be determinedCheck CRD missing or custom resource type
ComparisonErrorCannot render or compare Git sourceRepo creds, Helm/Kustomize render error

Application YAML

This is the core ArgoCD object: it tells ArgoCD which Git path to render and which cluster/namespace should receive the result. Use this as the starting point when onboarding one app or one environment into GitOps.

yaml application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-api
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io  # Ensures cascade delete on app removal.
spec:
  project: platform
  source:
    repoURL: https://github.com/example/platform-apps.git
    targetRevision: main
    path: apps/web-api/overlays/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: app
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

AppProject

An AppProject is the guardrail around Applications. Use it to restrict which Git repos, clusters, namespaces, and Kubernetes resource types a team can deploy through ArgoCD.

yaml appproject.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: platform
  namespace: argocd
spec:
  sourceRepos:
    - https://github.com/example/platform-apps.git
  destinations:
    - namespace: app
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:
    - group: "*"
      kind: "*"
  namespaceResourceWhitelist:
    - group: apps
      kind: Deployment

Helm Source

This fragment shows how an ArgoCD Application renders a Helm chart and applies environment-specific values. Use it when ArgoCD owns the release lifecycle but Helm still provides the app packaging.

yaml helm-application.yaml
source:
  repoURL: https://github.com/example/platform-apps.git
  targetRevision: main
  path: charts/web-api
  helm:
    valueFiles:
      - values-prod.yaml
    parameters:
      - name: image.tag
        value: "abc123f"   # Prefer Git commits over UI parameter edits.

Kustomize Source

This source points ArgoCD at a Kustomize overlay. Use it when the repo has a shared base and separate overlays for dev, staging, prod, or client-specific environments.

yaml kustomize-application.yaml
source:
  repoURL: https://github.com/example/platform-apps.git
  targetRevision: main
  path: apps/web-api/overlays/prod   # Must contain kustomization.yaml.

ignoreDifferences

Suppress known drift fields — common for HPA-managed replicas or mutating webhooks that add annotations.

yaml ignore-differences.yaml
spec:
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas          # HPA manages replica count.
    - group: autoscaling
      kind: HorizontalPodAutoscaler
      jqPathExpressions:
        - .status.currentReplicas

CLI & kubectl

Use these commands during incidents to find the owning Application, compare Git against live state, and inspect sync health before editing resources manually.

bash argocd-checks.sh
kubectl get applications -n argocd
kubectl describe application web-api -n argocd
kubectl logs -n argocd deploy/argocd-application-controller --tail=100

argocd app get web-api
argocd app diff web-api
argocd app sync web-api --prune
argocd app history web-api
argocd app rollback web-api <history-id>

Safe Client Workflow

  1. Find the owning Application: kubectl get applications -A | grep <app>
  2. Patch Git/Helm values/Kustomize overlays — not live resources unless incident process allows it.
  3. Review argocd app diff before sync.
  4. Watch rollout, events, and metrics after sync.
  5. Rollback via Git revert or argocd app rollback per client policy.

Gotchas

  • !selfHeal reverts kubectl edits — expected behavior; fix Git instead.
  • !Helm hooks may not run the same way as direct helm upgrade — test hook behavior explicitly.
  • !Do not helm upgrade an ArgoCD-managed release unless emergency process allows it.
  • !Prune deletes resources removed from Git — review diffs carefully in prod.