GitOps#

GitOps is declarative state in a Git repository, plus a controller that reconciles the running system to match. Coined by Weaveworks in 2017; codified by the OpenGitOps working group; the dominant delivery model in cloud-native shops by 2026.

        flowchart LR
  Dev[Engineer] -->|edit + PR| Repo[(Git Repo)]
  CI[CI] -->|build artifact| Reg[(Registry)]
  CI -->|update manifest| Repo

  Repo -->|polled / webhook| Ctrl[GitOps Controller]
  Ctrl -->|apply| Cluster[Kubernetes Cluster]
  Cluster -->|status| Ctrl
  Ctrl -->|drift / sync status| Repo

  Cluster -.->|metrics + logs| Obs[Observability]
    

The Four Principles#

OpenGitOps’ four principles distill the idea:

  1. Declarative, the desired state of the system is described declaratively.

  2. Versioned and immutable, the desired state is stored in a way that enforces immutability and versioning, with full history. Git.

  3. Pulled automatically, approved changes are pulled and applied to the system automatically.

  4. Continuously reconciled, a software agent ensures correctness and alerts on divergence.

Push-based deploys (CI runs kubectl apply) violate principles 3 and 4. GitOps insists on a controller in the cluster.

Push CD vs. Pull GitOps#

Push (classic CD)

Pull (GitOps)

CI runs kubectl apply.

Controller in the cluster syncs from Git.

CI needs cluster credentials. Cluster needs read access to Git only.

Drift goes undetected.

Drift is reconciled or alerted.

Rollback = run pipeline.

Rollback = revert commit.

Hard to multi-cluster.

Each cluster pulls its own desired state.

The pull model also closes a security hole: production clusters don’t need to expose APIs to a CI runner.

The Tools#

The GitOps controllers an operator picks among. Argo CD is the most popular, with an application-centric UI and rich RBAC; Flux is CNCF-graduated and modular; Kapitan and kpt sit at the configuration management edge; image updaters automate tag bumps in Git when new images land.

  • Argo CD, the most popular; application-centric model with a UI, RBAC, sync waves, hooks.

  • Flux, CNCF graduated; modular toolkit (source-controller, kustomize-controller, helm-controller).

  • Argo Workflows – not strictly GitOps; complements Argo CD for pipeline-shaped work.

  • kapitan, kpt – config-management adjacents.

  • werf, combined build + GitOps deploy.

  • FluxCD Image Automation, Argo Image Updater, bump image tags in Git when a new image is pushed.

A Typical Setup#

Two repositories (or one monorepo with two roots):

  • App repo, source code, Dockerfile, CI that builds + pushes the image. CI never touches the cluster.

  • Manifests repo, Kubernetes YAML / Helm values / Kustomize overlays per environment. Git-protected; PRs required.

Workflow:

  1. Developer pushes app code → CI builds image → pushes to registry.

  2. CI updates the image tag in the manifests repo (or an image-updater does it asynchronously).

  3. PR is reviewed; merge happens.

  4. Argo CD / Flux sees the change and applies it to the cluster.

  5. The cluster reports status; dashboards show sync state.

Rollback: revert the commit. The controller reconciles to the previous state.

Environments and Promotion#

  • Branch-per-environment, main for dev, staging for staging, main for prod. Promotions = merges between branches. Increasingly out of fashion (drift between branches is painful).

  • Folder-per-environment, a single branch with envs/dev/, envs/staging/, envs/prod/ directories. Promotion = PR that copies values forward. The 2026 default.

  • Pull-request-driven, each environment has its own folder; promotion is a script that opens a PR.

Tools that orchestrate promotion: Kargo, Argo Rollouts (for canary mechanics), GitHub Actions / Argo Workflows.

Secrets in GitOps#

Secrets in Git are not secrets. Three accepted patterns:

  • Sealed Secrets, Bitnami’s CRD; encrypts to a cluster-specific public key. The encrypted form is safe in Git.

  • External Secrets Operator, ESO syncs from a secrets manager (AWS Secrets Manager, GCP Secret Manager, Vault, Doppler) into Kubernetes Secrets.

  • SOPS + age / KMS, encrypted manifests in Git; the controller decrypts at apply time. Flux supports it natively.

Pick one and stick to it; mixing produces mystery.

Strengths#

The reasons GitOps won the cloud-native delivery debate. Auditable history via git log, reproducible cluster state, self-healing reconciliation, painless multi-cluster, no cluster credentials in CI, and a workflow operators already know; each is a real operational improvement.

  • Auditable, every change is a commit; git log is the audit trail.

  • Reproducible, the cluster’s state at time T is the Git history at T.

  • Self-healing, accidental kubectl edit is reverted to the declared state.

  • Easy multi-cluster, N clusters pulling from N folders.

  • Secure, CI doesn’t need cluster credentials.

  • Familiar workflow, operators already know Git.

Weaknesses#

The flip side. Imperative operations don’t fit; sync delays add minutes between merge and apply; drift on controller-unmanaged objects is invisible; repo organization becomes its own discipline; secrets need extra tooling; and bootstrapping the controller itself has a chicken-and-egg.

  • Not a fit for genuinely imperative operations, one-off scripts, database migrations, manual interventions.

  • Sync delays, a few seconds to minutes between merge and apply.

  • Drift on objects the controller doesn’t manage, kubectl patch outside the manifest is invisible.

  • Repo organization is its own art, ApplicationSets, app-of-apps, matrix generators. Misuse leads to spaghetti.

  • Secrets require extra tooling.

  • Cluster bootstrap chicken-and-egg, something has to install the GitOps controller; usually IaC + a bootstrap script.

Beyond Kubernetes#

GitOps is mostly Kubernetes-shaped today, but the model generalizes:

  • Atlantis for Terraform, PR comments trigger plan/apply.

  • Crossplane, Kubernetes-native cloud provisioning; combine with Argo CD / Flux for cross-cloud GitOps.

  • Pulumi GitOps, Pulumi’s deployment service.

  • Spacelift / Env0 / Terraform Cloud, managed Terraform with GitOps semantics.

The principles (declarative, versioned, pulled, reconciled) apply to anything that can be expressed declaratively.

When to Adopt#

  • You’re on Kubernetes (or moving there).

  • You have multiple environments / clusters.

  • You want auditability and reproducibility.

  • You want to reduce the trust given to CI runners.

If you have one cluster and three engineers, classic kubectl apply in CI may be cheaper. The benefits scale with cluster count, team count, and audit requirements.

See Also#