GitOps with ArgoCD: Kubernetes Continuous Delivery at Scale
GitOps flips the traditional CD model. Instead of pushing deployments from a CI system, the cluster pulls its desired state from Git. ArgoCD is the most widely adopted implementation — and it changes how teams think about deployment safety, auditability, and multi-environment management.
Introduction
Traditional continuous deployment uses a push model: a CI pipeline builds an artifact and then runs kubectl apply or calls the Kubernetes API directly to deploy changes. This works for small teams with one or two clusters. As organizations scale to dozens of services, multiple environments, and several clusters, push-based CD creates serious problems: deployment credentials scattered across CI systems, no systematic drift detection, and difficult incident recovery when cluster state diverges from intended configuration.
GitOps inverts this model. Git becomes the single source of truth for the desired state of every Kubernetes resource. A GitOps operator running inside the cluster watches Git repositories and reconciles the live cluster state to match. Deployments happen by merging a PR. Rollbacks happen by reverting a commit. Audit trails are commit histories. ArgoCD is the most widely deployed GitOps operator in the ecosystem, powering continuous delivery for thousands of Kubernetes clusters in production.
Problem Statement: Why Push-Based CD Breaks at Scale
When your CI pipeline deploys directly to clusters, you accumulate multiple problems. First, you need to grant CI runner credentials to every cluster — a significant security surface area. Second, if someone applies a manual hotfix directly with kubectl, your Git repository no longer reflects cluster reality. This drift is invisible until something breaks. Third, promoting the same artifact across dev, staging, and production environments requires increasingly complex pipeline logic. Fourth, incident recovery is painful: to understand what changed, you must reconstruct the deployment history from CI logs rather than Git commits.
GitOps with ArgoCD solves all four problems. No CI credentials in cluster. Drift is detected automatically and either auto-corrected or alerted. Promotions are PR-based config changes. Recovery is a Git revert.
ArgoCD Architecture: How It Works
ArgoCD deploys as a set of Kubernetes components: an API server, a repository server (that clones and renders Git repos), an application controller (that compares live state to desired state), and a Dex-based OIDC server for authentication. The application controller polls Git repositories at configurable intervals (default three minutes) and on webhook triggers for push events, then applies the diff to the cluster using standard Kubernetes API calls.
The central abstraction is the Application CRD. Each Application points to a Git source (repo URL, path, target revision) and a destination (cluster, namespace). ArgoCD computes the diff between the rendered manifests from Git and the live Kubernetes resources, then either syncs automatically or waits for manual approval depending on your sync policy.
Application Configuration Example
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: payment-service
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: HEAD
path: apps/payment-service/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: payments
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
The selfHeal: true flag means ArgoCD will automatically re-sync if manual changes are detected in the cluster. This is the GitOps invariant: cluster state must always match Git. The prune: true flag ensures resources removed from Git are also removed from the cluster.
ApplicationSets: Scaling Across Environments and Clusters
Managing 50 individual Application objects for 10 services across 5 environments becomes tedious. ApplicationSets solve this with a generator-based templating system. You define one ApplicationSet and a generator that produces Application objects from a list, a Git directory structure, or a cluster selector.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: microservices
namespace: argocd
spec:
generators:
- matrix:
generators:
- list:
elements:
- service: order-service
- service: inventory-service
- service: payment-service
- list:
elements:
- env: staging
- env: production
template:
metadata:
name: '{{service}}-{{env}}'
spec:
source:
repoURL: https://github.com/myorg/k8s-manifests
path: 'apps/{{service}}/overlays/{{env}}'
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: '{{env}}'
This single ApplicationSet generates six Application objects (three services × two environments) automatically. Adding a new service means adding one entry to the list — not creating and configuring a new Application object manually.
Multi-Cluster GitOps: Hub-Spoke Architecture
For organizations running multiple Kubernetes clusters (separate clusters per region or per environment boundary), ArgoCD supports a hub-spoke model. A single ArgoCD instance (the hub) manages multiple remote clusters. Each cluster is registered with an ArgoCD service account, and Applications target specific cluster API server URLs. This centralizes visibility and audit while clusters remain operationally independent.
For very large scale or strict network isolation requirements, the App of Apps pattern allows a root Application that deploys other Applications — effectively bootstrapping an entire cluster environment from a single Git commit.
Drift Detection and Self-Healing
One of ArgoCD's most valuable production capabilities is drift detection. With selfHeal enabled, any manual kubectl apply that deviates from Git state is automatically reversed within the next sync cycle. This is a powerful operational guarantee: Git is always truth, and production cannot drift silently for days without detection.
For cases where you genuinely need to allow temporary manual overrides — for example, emergency scaling during an incident — you can pause auto-sync for an Application from the ArgoCD UI or CLI. The pause is visible to the team and time-limited, ensuring it is not forgotten.
RBAC: Secure Multi-Tenant Access
ArgoCD's RBAC model assigns roles to users and groups mapped from your identity provider. At minimum, define three roles: read-only for developers browsing application state, sync permissions for CI/CD pipelines triggering manual syncs, and admin for platform engineers managing Application and AppProject configuration. Use AppProjects to restrict which Git repos and which clusters each team can target. This prevents accidental or malicious cross-team deployments.
ArgoCD vs Flux: Choosing the Right Tool
Flux (part of the CNCF ecosystem) is the other widely adopted GitOps operator. Flux is more modular — controllers for image automation, Helm releases, Kustomization, and notification are separate components. ArgoCD provides a richer UI and a centralized multi-app view out of the box. For teams that prioritize a strong operator UI and multi-cluster application visibility, ArgoCD is usually the better choice. For teams that prefer minimal-footprint GitOps deeply integrated with Helm and Flux's notification ecosystem, Flux is a strong alternative. Both are production-ready and CNCF-graduated.
Pros and Cons
Pros of GitOps with ArgoCD: Declarative, auditable deployments with full Git history. Automatic drift detection and correction. No cluster credentials needed in CI pipelines. Multi-cluster visibility in a single UI. Strong RBAC and project isolation. Widely adopted with a large community.
Cons: ArgoCD itself is an operational component that requires maintenance, HA configuration, and backup of its Application CRDs. Pull-based sync has a polling lag (minutes, not seconds) that may require webhook configuration for faster feedback. Secrets management requires a complementary tool (Sealed Secrets, External Secrets Operator, or Vault) since raw secrets should never be committed to Git.
Common Mistakes
Committing secrets to the GitOps repo: Use External Secrets Operator or Sealed Secrets. Never store raw Kubernetes Secret manifests in Git.
Enabling auto-sync and prune on production without testing: Start with sync disabled in production. Validate behavior in staging. Enable automated sync with prune only after you trust the Git state completely.
Ignoring ArgoCD HA for production: The default single-replica installation is not suitable for production. Run ArgoCD in HA mode with at least two replicas of the application controller and API server.
Key Takeaways
- GitOps makes Git the single source of truth for cluster state, enabling auditable and recoverable deployments.
- ArgoCD's Application CRD points to a Git path and a cluster destination, reconciling them continuously.
- ApplicationSets scale GitOps to dozens of services and environments with minimal configuration overhead.
- selfHeal automatically corrects cluster drift; paired with drift alerts it provides a strong operational guarantee.
- Never commit secrets to Git — use External Secrets Operator or Sealed Secrets as a complement.
Conclusion
GitOps with ArgoCD is the modern standard for Kubernetes continuous delivery in organizations running multiple services and environments. It reduces deployment risk by making changes auditable and reversible, eliminates credential sprawl in CI systems, and gives platform teams reliable drift detection. The operational investment — running ArgoCD in HA, structuring your Git repository cleanly, and choosing a secrets management strategy — pays off quickly for any team managing more than a handful of Kubernetes applications. Start with a non-production cluster, master the Application and ApplicationSet models, then expand to production with automated sync and selfHeal enabled.
Related Articles
Share your thoughts
Are you using ArgoCD or another GitOps tool in production? Share your thoughts below.