← all writeups
Moving three clusters to GitOps
Replacing hand-run kubectl and a deploy script nobody wanted to own with ArgoCD and one repo of truth.
- Date
- 2025-08-14
- Type
- build
- Duration
- 7 weeks
- Impact
- 140 applications migrated. Config drift went from weekly to zero in the following quarter.
PLACEHOLDER POST — seed data. Replace with your real writeup.
Before this project, “what is running in production” was answered by
kubectl get and hope. Deploys went through a 900-line bash script with three
authors, none of whom still worked on the team.
Where we started
- 3 clusters (dev, staging, prod), each slightly different in ways nobody had written down
- Helm releases installed from laptops
- Hotfixes applied with
kubectl edit, and never committed
What we built
One platform-apps repo using the app-of-apps pattern. Each environment is a
directory of values overlays. ArgoCD ApplicationSets generate one Application
per service per cluster.
generators:
- matrix:
generators:
- clusters: { selector: { matchLabels: { tier: workload } } }
- git: { directories: [{ path: "apps/*" }] }
How we migrated without breaking anything
- Import each live release in
manualsync with self-heal off, and diff it - Commit whatever the live cluster actually had, even when it was wrong
- Fix the drift in a separate PR, so every fix was reviewed
- Enable auto-sync one namespace at a time, starting with dev
What I’d do differently
Start with the drift report. Showing the team how far live state had wandered from the repo made the case for GitOps better than any design doc did.
← all writeups