Cloud Tech by Victor
DevOpsIntermediate

GitOps Principles

Why treating Git as the single source of truth for cluster state, instead of running kubectl/terraform apply by hand, changes how deployments, rollbacks, and audits actually work.

Updated 2026-07-223 min read

Overview

GitOps is an operating model, not a specific tool: the desired state of a system is declared in a Git repository, and an automated agent continuously reconciles the live system toward whatever that repository currently describes. The practical difference from "we deploy via CI" is the direction of control, a CI pipeline pushes changes out on trigger, while a GitOps agent pulls from Git on a loop and keeps enforcing it, catching and correcting drift even if nobody touched the pipeline. That single property, a continuously enforced, Git-sourced desired state, is what gives GitOps its rollback, audit, and drift-detection properties essentially for free.

Quick Reference

ConceptWhat it means
Source of truthGit repository, not the live cluster
ReconciliationPull-based, continuous, an in-cluster agent compares and corrects drift
RollbackA Git revert, using the same mechanism as any other change
Audit trailGit commit history, author, timestamp, review, diff
DriftAny live-state divergence from Git is automatically detected and (optionally) corrected

Syntax

yaml
# Argo CD Application - points a cluster at a Git path and keeps it in sync
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api
spec:
  source:
    repoURL: 'https://github.com/org/infra-config'
    path: apps/api
    targetRevision: main
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: api
  syncPolicy:
    automated:
      selfHeal: true
      prune: true

Examples

bash
# A rollback is just a Git revert - no separate rollback tooling
git revert HEAD
git push origin main
# The GitOps agent detects the new commit and reconciles the cluster
# back to the previous declared state automatically.

selfHeal vs manual sync

selfHeal: true makes the agent correct drift automatically, even without a new commit, someone manually editing a live resource gets silently reverted. Some teams prefer manual sync approval for production, trading that safety net for an explicit human confirmation step.

Visual Diagram

Common Mistakes

  • Confusing "we deploy from a CI pipeline triggered by Git" with GitOps, without a continuous, pull-based reconciliation loop, there's no drift detection or self-healing, just a scripted push.
  • Granting engineers standing kubectl apply access to production alongside a GitOps agent, any manual change either gets silently reverted (confusing) or causes permanent drift (defeats the point).
  • Storing secrets in plaintext in the Git repository that GitOps reconciles from, the repository needs the same access control as production credentials, or secrets need to be kept out of it entirely (sealed secrets, external secret managers).
  • Treating the GitOps repository structure as an afterthought, a disorganized repo with unclear environment boundaries makes "what's actually running in production" as hard to answer as it was before GitOps.

Performance

  • Reconciliation interval (how often the agent polls or reacts to Git changes) trades responsiveness for load on the Git provider and cluster API, very tight intervals on a large cluster with many Applications can add real API server pressure.
  • Large repositories with many resources per sync can make individual reconciliation passes slow; splitting by application or environment (multiple smaller Application/Kustomization objects) keeps each sync fast and isolates blast radius.
  • Self-healing on every drift detection adds reconciliation overhead but is usually worth it; the alternative is silent, undetected drift accumulating over time.

Best Practices

  • Keep application config and infrastructure config in separate repositories or clearly separated paths, since they change at different rates and often need different review policies.
  • Require pull-request review on the GitOps repository for anything touching production; this is the actual audit/approval mechanism, so it needs to be enforced, not optional.
  • Keep secrets out of the plain Git repository (sealed secrets, external secret operators) even though everything else lives there.
  • Start with manual sync approval for production and move to automated self-heal only once the team trusts the pipeline and monitoring around it.

Interview questions

What makes a workflow "GitOps" rather than just "we deploy from CI"?

The defining property is a pull-based reconciliation loop, not just that Git triggers a deploy. A GitOps agent (Argo CD, Flux) runs inside the cluster and continuously compares the live state against what's declared in a Git repository, pulling and applying any drift, with or without a new commit. A CI pipeline that runs `kubectl apply` on push is push-based: it changes things once, on trigger, and has no ongoing awareness of whether the cluster later drifts from that state. GitOps closes that loop continuously and treats Git, not the cluster, as the source of truth.

How does GitOps make rollbacks different from a traditional deployment rollback?

In a traditional deploy, rolling back means re-running a deployment process with an older artifact reference, a distinct operation from a normal deploy. In GitOps, a rollback is just a Git revert: since the desired cluster state is fully described by the repository at any commit, reverting to a previous commit and letting the reconciliation loop pick it up produces the previous cluster state through the exact same mechanism as any other change. There is no separate "rollback pipeline" to maintain or that can itself have bugs.

Why does GitOps improve auditability compared to engineers running kubectl or terraform apply directly?

Every change to cluster state has to go through a Git commit, which means it inherits Git's existing history, authorship, and (if branch protection is configured) pull-request review, automatically. Direct `kubectl apply` access leaves no equivalent trail: two changes with the same effect are indistinguishable, there's no required review step, and reconstructing "who changed what and why" after an incident means digging through cluster event logs instead of reading a linear, reviewed commit history.

References

ShareXLinkedInReddit
Was this page helpful?
Suggest an improvement