Skip to content

GitOps and ArgoCD

★★★★★ Intermediate

GitOps uses Git as the single source of truth for infrastructure and application state. An operator inside the cluster watches Git repos and automatically reconciles cluster state to match - providing self-healing, audit trails, and declarative deployments.

GitOps Core Principles

  1. Declarative descriptions - system state in files (K8s manifests, Terraform configs)
  2. Git as source of truth - all changes versioned in Git
  3. Automated delivery - CI/CD pipelines
  4. Automatic reconciliation - operators detect and fix drift

Pull Model

Operator (ArgoCD/Flux) inside cluster independently checks Git and updates cluster. No external CI system pushes to cluster.

Flow: Developer -> Git -> CI builds image -> Update manifest in Git -> ArgoCD detects change -> Deploys to cluster

Self-Healing

If cluster deviates from desired state (e.g., pod deleted manually), ArgoCD automatically restores it.

ArgoCD

Installation

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Access
kubectl port-forward svc/argocd-server -n argocd 8080:443
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

CLI

argocd login <SERVER> --username admin
argocd repo add <url>                              # public repo
argocd repo add <url> --username <u> --password <p> # private
argocd repo add <url> --ssh-private-key-path ~/.ssh/id_rsa

argocd app sync <app-name>     # manual sync
argocd app get <app-name>      # status
argocd app list                # all apps

Sync Modes

  • Automatic - Git changes applied immediately
  • Manual - user confirms via UI or CLI

Features

  • State synchronization with drift detection
  • Multi-cluster management (dev, staging, prod)
  • Web UI with diff views, pod logs, topology
  • RBAC for access control
  • ApplicationSet for auto-creating apps from templates
  • Works with Jenkins, GitLab CI, GitHub Actions

App of Apps Pattern

One parent Application manages multiple child applications:

  • Parent references a Git repo containing child application manifests
  • Single point of control for entire cluster state
  • Adding new components = adding new manifest
  • Disaster recovery: entire cluster recoverable from Git

Sync Waves

Order resource deployment via annotations:

metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "1"

Deployment order: Wave -1 -> Wave 0 -> Wave 1 -> Wave 2 (2s pause between). Deletion happens in reverse order.

Typical ordering: 1. Namespaces, CRDs (wave -1) 2. Databases, infrastructure (wave 0) 3. Backend services (wave 1) 4. Frontend services (wave 2)

Sealed Secrets

Encrypted secrets safe for Git storage:

# kubeseal encrypts with cluster's public key
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
# Only the cluster with matching private key can decrypt

SealedSecret controller in cluster decrypts at runtime.

Crossplane (K8s-Native IaC)

Alternative to Terraform that runs inside the cluster:

  • Extends K8s API with CRDs representing cloud infrastructure
  • Uses K8s reconciliation loop for continuous drift detection
  • Developer self-service via Claims
  • Providers: provider-aws, provider-gcp, provider-kubernetes

vs Terraform: runs inside K8s, native RBAC, continuous reconciliation (not just plan/apply).

Terraform in GitOps

  1. Store Terraform configs in Git
  2. On PR: auto-run terraform plan
  3. After merge to main: auto-run terraform apply
  4. Changes go through PR review

Gotchas

  • Secret management requires additional tools (Sealed Secrets, Vault, External Secrets Operator)
  • Adding new environments requires Git repo edits
  • ArgoCD itself needs to be managed (who deploys ArgoCD?)
  • Sync waves only work within a single Application resource
  • Image tag updates should modify Git manifests, not be pushed directly

See Also