Traditional CI/CD works like this: pipeline builds the code, then pushes it to the cluster. GitOps flips that model — the cluster pulls the desired state from Git. It’s a subtle difference, but it changes everything.
GitOps Principles
There are four core ideas:
- Git is the single source of truth — everything (app manifests, infra config, even policies) lives in Git
- Declarative desired state — we describe what we want, not how to get there
- Automated reconciliation — an agent constantly compares the actual state with Git and fixes any drift
- Changes through PRs only — no one
kubectl applys from their laptop. Every change goes through a pull request
In simple language, GitOps means: if it’s not in Git, it doesn’t exist. And if Git says “3 replicas,” the cluster will have 3 replicas — always.
Push vs Pull Model
The pull model is more secure because our CI pipeline never needs cluster credentials. The agent inside the cluster does all the work.
ArgoCD Basics
ArgoCD is the most popular GitOps tool for Kubernetes. It runs inside our cluster and watches a Git repo for changes.
The core concept is the Application CRD — a custom resource that tells ArgoCD: “watch this Git repo, this path, and sync it to this namespace.”
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/my-app # folder containing K8s manifests
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated: # auto-sync when Git changes
prune: true # delete resources removed from Git
selfHeal: true # fix manual changes (drift)
Key sync policies:
- Auto-sync — ArgoCD applies changes automatically when it detects a new commit
- Prune — if we delete a manifest from Git, ArgoCD deletes the resource from the cluster
- Self-heal — if someone manually edits a resource in the cluster, ArgoCD reverts it to match Git
Drift Detection
This is where GitOps really shines. If someone SSH’s into the cluster and runs kubectl scale deployment my-app --replicas=1 (maybe during a panic), ArgoCD detects that the cluster state doesn’t match Git and automatically reverts it.
No more “who changed this in production?” mysteries. Git history is the complete audit log.
Why GitOps Matters for Auditing
Every change is a Git commit. That means:
- We know who changed what (commit author)
- We know when it changed (commit timestamp)
- We know why it changed (PR description)
- We can revert any change by reverting the commit
For regulated industries (finance, healthcare), this audit trail is gold. No more “we think someone ran this command last Tuesday.”
The Typical GitOps Workflow
# 1. Developer changes app code, pushes to app repo
# 2. CI pipeline builds image, tags it (e.g., v1.2.3)
# 3. CI updates the image tag in the manifests repo
# 4. ArgoCD detects the change in the manifests repo
# 5. ArgoCD syncs the new image to the cluster
# 6. If something breaks, revert the manifest commit
In simple language, GitOps is version control for our entire infrastructure. We already trust Git with our code — GitOps extends that trust to deployments, config, and everything else running in production.