Argo CD GitOps Workflow Explained: Architecture and Implementation
Argo CD implements a declarative GitOps continuous delivery pipeline that continuously compares desired state stored in Git with live Kubernetes cluster state, automatically reconciling drift through a controller loop that executes seven distinct stages from source fetch to status update.
Argo CD is a Kubernetes-native continuous delivery tool maintained in the argoproj/argo-cd repository. It enforces the GitOps methodology by treating Git repositories as the single source of truth for application definitions. Understanding the Argo CD GitOps workflow requires examining how the ApplicationController orchestrates manifest generation, diff calculation, and synchronized deployment without manual intervention.
The Seven Stages of the Argo CD GitOps Workflow
The workflow progresses through seven logical stages implemented across the controller and gitops-engine packages. Each stage handles a specific transformation from source code to running cluster resources.
1. Source Fetch
The controller reads the Git, OCI, Helm, Kustomize, or Jsonnet repository defined in an Application resource. In controller/appcontroller.go (lines 18-23), the ApplicationController initializes a RepoServer client to fetch raw manifests from the configured source location.
2. Manifest Generation (Hydration)
When the source uses templating tools, the hydrator renders "dry" manifests into plain Kubernetes YAML. The implementation in controller/hydrator/hydrator.go defines hydrator.Dependencies and produces fully rendered manifests required for accurate cluster comparison.
3. Diff and Health Analysis
The rendered manifests are compared against live objects in the target cluster. The controller invokes argodiff.StateDiff (lines 438-447 in controller/appcontroller.go utilizing gitops-engine/v3/pkg/diff) to calculate declarative differences while masking secret data. Simultaneously, gitops-engine/v3/pkg/health determines resource health status, marking any divergence as OutOfSync.
4. Sync Decision
Based on Application.Spec.SyncPolicy and user requests, Argo CD decides whether to auto-sync, manually sync, or skip reconciliation. The ApplicationController.requestAppRefresh method (lines 998-1016) queues refresh requests into the appRefreshQueue when drift is detected.
5. Apply Changes
Argo CD generates a patch or full manifest and applies it to the target cluster using the Kubernetes client abstraction. The controller utilizes kube.Kubectl (lines 22-24) while respecting configured parallelism limits (lines 36-38) to prevent API server overload during bulk operations.
6. Status Update
After operations complete, the controller updates the Application status with sync results, health conditions, and resource metadata. The setAppManagedResources method (lines 998-1020 in controller/appcontroller.go) persists these updates, while operational metrics are recorded via metrics.MetricsServer.
7. Events and Metrics
All actions generate audit events via argo.AuditLogger and Prometheus metrics through controller/metrics/metrics.go. These components are instantiated during NewApplicationController initialization (lines 21-31), providing complete observability into the reconciliation loop.
Continuous Reconciliation Architecture
Argo CD runs a watch using the Kubernetes informer pattern on Application CRDs hosted in the cluster. When changes occur in Git (triggered by webhooks or periodic polling) or in live cluster resources, the controller enqueues a refresh request to the appRefreshQueue. Worker threads process these requests asynchronously, guaranteeing eventual consistency between the version-controlled desired state and the actual cluster state.
The source of truth remains exclusively the Git repository. All changes applied to the live cluster trace back to specific commits, enabling complete audit trails and simple rollbacks by reverting Git history.
Key Implementation Files
Understanding the Argo CD GitOps workflow requires familiarity with these critical source locations:
controller/appcontroller.go– Main controller loop, queue handling, and sync orchestrationcontroller/hydrator/hydrator.go– Renders Helm/Kustomize/Jsonnet templates into executable YAMLgitops-engine/v3/pkg/diff– Calculates declarative differences between desired and live stategitops-engine/v3/pkg/health– Determines real-time health status of Kubernetes resourcescontroller/metrics/metrics.go– Exposes Prometheus metrics and tracks kubectl usage patternscontroller/sharding/sharding.go– Distributes workload across multiple controller replicas for horizontal scalingutil/db/db.go– Persists application state in a ConfigMap-backed database
Practical Example: From Git Commit to Live Cluster
Below is a minimal Application resource demonstrating automated synchronization:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/guestbook
targetRevision: HEAD
path: kustomize
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
The execution flow follows these steps:
- Git Fetch – The controller contacts the repo server via
repoClientsetand pulls thekustomizedirectory atHEAD. - Hydration – Kustomize renders the files into canonical YAML manifests through the hydrator.
- Diff Calculation –
argodiff.StateDiffcompares rendered manifests against objects currently in thedefaultnamespace. - Automatic Sync – Because
automated.selfHealis enabled, detected drift triggerskubectl applythrough thekube.Kubectlwrapper. - Status Recording – The
Applicationstatus updates toSyncedand records the specific commit SHA that produced the live state.
Summary
The Argo CD GitOps workflow consists of tightly integrated components that automate Kubernetes deployments:
- Application CR declares what should run and where, storing references to the desired state in Git.
- ApplicationController manages the core reconciliation loop, fetching source, rendering manifests, and applying changes.
- Hydrator converts template-based configurations into concrete Kubernetes YAML before comparison.
- Diff and Health Engine calculates drift and determines whether resources are healthy, degraded, or missing.
- Sharding enables horizontal scaling across multiple controller replicas for high-volume environments.
- Metrics and Auditing provide operational visibility and immutable audit trails for compliance.
This architecture ensures the live cluster always reflects the version-controlled desired state without requiring manual kubectl operations.
Frequently Asked Questions
How does Argo CD detect changes in the Git repository?
Argo CD detects changes through webhook notifications from Git providers that trigger immediate reconciliation, and through periodic polling intervals that scan repositories for new commits. When either mechanism identifies drift, the controller enqueues a refresh request to the appRefreshQueue for processing by worker threads according to the logic in controller/appcontroller.go.
What is the difference between auto-sync and manual sync in Argo CD?
Auto-sync automatically applies changes when drift is detected between Git and the cluster, configured via syncPolicy.automated in the Application spec with options like prune and selfHeal. Manual sync requires explicit user approval through the UI or CLI before the controller executes any changes. Auto-sync provides hands-free continuous delivery, while manual sync offers greater control for production environments requiring change review.
How does Argo CD handle secret management during the diff process?
According to the implementation in gitops-engine/v3/pkg/diff, Argo CD masks sensitive data during diff calculations to prevent secret values from appearing in logs and UI displays. The diff engine compares live state against desired state while redacting secret contents, ensuring security compliance while still identifying configuration drift in non-sensitive fields.
Can Argo CD scale to manage thousands of applications?
Yes, Argo CD supports horizontal scalability through sharding implemented in controller/sharding/sharding.go. Multiple controller replicas run simultaneously, with each replica processing a distinct shard of applications based on cluster hostname or application UID. This distribution prevents any single controller from becoming a bottleneck and enables high-availability deployments across multiple nodes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →