im·a·cto
← choices

$ cat choices/argo-cd.md

Argo CD

the call

I reach for Argo CD when Kubernetes deploys should be GitOps: git holds the desired state, Argo reconciles the cluster to match, and every change is a reviewable diff with a one-line rollback. It's the app-delivery half that Terraform should never be doing, and I don't bolt it on before there's a cluster worth reconciling.

why

GitOps makes the deploy path boring, auditable, and reversible, which is exactly what you want a deploy path to be. The desired state of the cluster lives in git; Argo continuously reconciles the running cluster to match it. A deploy is a merged PR. A rollback is git revert. The audit log is git log. Drift, someone poking the cluster by hand, gets detected and surfaced instead of festering. You stop asking “what’s actually running?” and start reading it, the same way Terraform let you stop guessing what’s provisioned.

when I don’t

Argo CD earns its keep at Kubernetes scale: many services, multiple environments or clusters, more than one person shipping. It’s the wrong call before you’re there: a single small service doesn’t need a reconciliation control plane, it needs a CI step that pushes the image. Adding Argo to a one-box app is the same mistake as reaching for Kubernetes too early: overhead pretending to be rigor. Earn it.

in production

The pattern I run: Terraform provisions the cluster and everything under it; CI builds and tests the image; Argo CD deploys it by reconciling the cluster to what’s in git. Three tools, three jobs, three blast radii. Critically, the thing that ships ten times a day (the app) is decoupled from the thing that changes once a month (the infrastructure). That separation is the whole point: a routine deploy can never accidentally touch your VPC, and a rollback is a revert, not an act of courage.— see: choices / kubernetes · choices / terraform

the principle under it

Separate the slow-moving substrate from the fast-moving payload, and give each the tool that fits its speed. Infrastructure changes slowly and rolls back carefully; application code ships constantly and rolls back casually. Git can be the source of truth for both, but not the same pipeline for both. Most deploy-path pain is two things with different rhythms welded into one. Argo’s job is to own the fast half cleanly so the slow half stays untouched.

the gaps — what it costs even when it’s right

Not everything is declarative. Secrets, database migrations, and stateful cutovers don’t fit the “git is the desired state” model cleanly. You end up bolting on sealed-secrets, sync hooks, and migration jobs: real complexity the happy-path demos skip.

It’s another control plane to run. Argo is now a system you operate, monitor, secure, and upgrade. You bought reconciliation, and you pay for it in one more thing that can break. When it does, your deploys stop.

”Git is truth” only holds if nobody cheats. One hand-run kubectl apply and reality diverges from git. Argo will either loudly fight you or silently revert your hotfix. The model is only as honest as the team’s discipline about going through it.

© 2026 — written by a human, with help, and said so canonical jasonwaldrip.com · delivered through The Bushido Collective