GitOps
Concept
GitOps is an operating model where a Git repository is the single source of truth for a system's desired state — infrastructure configuration, Kubernetes manifests, application deployment specs — and an automated controller continuously reconciles the actual running state to match what's declared in Git, rather than a human or a CI pipeline pushing changes directly to production. Change happens through a pull request: someone proposes a diff to the declared state, it's reviewed and merged, and a reconciliation agent (Argo CD, Flux) running inside the target environment detects the drift between Git and reality and converges the cluster to match — pulling the change, not having it pushed to them from outside.
The distinction that matters is push vs. pull deployment. A traditional CI/CD pipeline has push-based access: the pipeline holds credentials to production and pushes changes into it directly, meaning production credentials live outside the cluster, in CI. GitOps flips this — the in-cluster agent has read access to Git and write access to its own cluster, but nothing external holds a standing credential to push into production. That inversion is also what gives GitOps its second core property for free: continuous drift detection. Because the agent is constantly comparing declared-state-in-Git to actual-state-in-cluster, any manual kubectl apply or console change that bypasses Git shows up immediately as drift and gets silently reverted (or flagged) back to what Git says — production can't quietly diverge from what's documented, because the documentation is the deployment mechanism.
Tradeoffs
| Property | Push-based CI/CD | GitOps (pull-based reconciliation) |
|---|---|---|
| Where production credentials live | In the CI/CD system, external to the cluster | Only inside the cluster's own reconciliation agent |
| Audit trail | Pipeline logs, potentially separate from the change history | Git history itself is the audit trail — every prod change is a commit |
| Drift detection | None by default — manual changes go untracked until someone notices | Continuous — any out-of-band change is detected and reconciled automatically |
| Rollback | Re-run a previous pipeline job, or manually revert | git revert — rollback is a Git operation, same review process as any other change |
| Setup complexity | Lower — most teams already have a CI pipeline | Higher — requires an in-cluster agent, repo structure conventions, and often a split between app-code repo and config repo |
The tradeoff is centralizing the security surface (fewer places hold production write credentials) and getting drift detection essentially for free, at the cost of a genuinely different operating model that requires more upfront tooling and discipline than "just add a deploy step to the existing pipeline."
When to use / when not to
- Use GitOps for Kubernetes-native environments where declarative manifests are already the natural unit of configuration — it's close to friction-free there and the tooling (Argo CD, Flux) is mature.
- The audit-trail and drift-detection properties are especially valuable in regulated environments (Fintech, Capital Markets) where "prove exactly who changed production and when, with review evidence" is a real compliance requirement Git history satisfies almost for free.
- Skip GitOps for systems that aren't naturally declarative or container-orchestrated — bolting a reconciliation loop onto a legacy imperative deploy process usually costs more than it returns.
- Skip it for a small team without existing Kubernetes/declarative-infra maturity — the tooling investment isn't worth it until the underlying infrastructure is already in that shape.
Common pitfall
Treating GitOps as "we deploy by merging to main" without the reconciliation loop — i.e., still push-deploying via CI, just triggered by a Git merge instead of a manual click. That gets the review-workflow benefit but none of the drift-detection or credential-centralization benefit, because there's still no agent continuously enforcing that reality matches Git; a manual kubectl edit in production goes just as undetected as it would under any other push-based pipeline.
Engineering Lens
GitOps is a genuinely different answer to "where does the authority to change production live," and articulating that shift precisely — credentials move from the pipeline into the cluster, drift becomes continuously detected instead of eventually discovered — is what separates understanding the pattern from just knowing the tool names. It's also a clean example of a security improvement (fewer standing external credentials to production) arriving as a side effect of an operability improvement (drift detection, Git-native rollback), which is exactly the kind of cross-pillar tradeoff worth calling out explicitly in an architecture review rather than filing GitOps purely under "deployment tooling."