Independent marketplace for cloud provider accounts across 22 providers

DevOps & Automation

GitOps Basics for Cloud Teams

GitOps is not simply keeping YAML in version control. This guide covers the four defining properties, why configuration lives in its own repository, how Argo CD and Flux reconcile drift, and the three usual answers to the secrets problem.

A cluster agent pulling declared state from a configuration repository and reconciling drift

A Word That Got Used Before It Was Defined

GitOps arrived as marketing shorthand and settled into something precise. It is not "we keep YAML in git", which almost everyone already does. It is a specific operating model where a running system continuously pulls its desired state from a repository and corrects itself when reality diverges.

The distinction matters because the two look identical on a diagram and behave very differently at three in the morning. In a push pipeline, a deployment is an event that happened. In GitOps, the desired state is a fact that keeps being true.

The OpenGitOps working group under the CNCF put names to the ideas, and the vocabulary below follows theirs.

The Four Properties

  • Declarative. The system is described by what it should be, not by the steps to get there.
  • Versioned and immutable. That description lives in version control, so every state has a commit and a history.
  • Pulled automatically. An agent inside the target environment fetches approved changes rather than receiving them from outside.
  • Continuously reconciled. Software constantly compares actual state against desired state and acts on the difference.

The third property is the one that changes your security posture. Nothing outside the cluster needs credentials to modify it, so there is no deployment key sitting in a CI system with permission to reshape production.

The fourth is the one that changes your operations. A manual change made during an incident does not persist quietly for six months. It is detected, reported, and usually undone.

The CNCF landscape lists the projects that implement this model among its graduated and incubating projects, which is a reasonable place to start evaluating maturity.

Why the Config Lives Somewhere Else

Most implementations separate the application repository from the configuration repository. Source code, tests and the image build live in the first. Manifests describing what runs where live in the second.

Splitting them avoids an unpleasant loop where a commit triggers a build that writes a tag back into the same repository, triggering another build. It also lets access differ: many people may merge application code, while far fewer may merge a change to the production configuration.

A common layout keeps a base set of manifests plus per environment overlays, so staging and production share structure and differ only where they genuinely should. Kustomize and Helm are the usual tools for expressing that, and the choice between them is mostly a matter of team taste.

The image tag in the configuration repository is the join between the two worlds. The build pipeline produces an image and a commit updates the reference, which is where the pipeline described in CI/CD pipelines that deploy to cloud servers hands over, and why the digest practices in container registries matter so much here.

The Two Agents You Are Likely to Meet

Argo CD and Flux dominate, both CNCF projects, both installed into the cluster they manage.

Argo CD presents a web interface that shows each application, whether it is synced, and a visual diff between the repository and the cluster. Teams adopting the model for the first time often prefer it because the state is legible without reading logs. Its source and installation notes live at the Argo CD repository.

Flux is a set of controllers with no interface of its own, configured entirely through custom resources. It appeals to teams that want the model expressed as Kubernetes objects and are comfortable observing it through their existing dashboards.

Both support the same essential behaviours: watch a path in a repository, render manifests, apply them, report drift, and optionally prune resources that have disappeared from the source. Both can also watch a registry and open a commit when a new image tag appears, which automates the join described above.

The environment they need is a Kubernetes cluster, which is the main prerequisite. Whether that is reasonable for a small team is weighed up in managed Kubernetes for small teams.

What Reconciliation Feels Like Day to Day

Once an agent is running, the cluster develops opinions. Edit a live deployment by hand and within a minute the change is reverted, because the repository says otherwise.

That is correct behaviour and it is also a genuine adjustment. Emergency fixes now go through a commit, which is slower in the moment and dramatically better afterwards, because the fix is recorded and survives the next sync. Most tools offer a temporary pause for exactly the cases where a human must intervene first and document second.

Pruning deserves a deliberate decision. With it enabled, deleting a manifest deletes the resource, which is the clean behaviour you want and also a way to remove something important with a single merge. Many teams enable pruning in non production first and add branch protection before turning it on for production.

The Obvious Objection: Secrets in a Repository

The model wants everything in version control. Database passwords and API tokens must not be. Three approaches resolve this, and they are not mutually exclusive.

Encrypt before committing. Tools such as SOPS encrypt values with a key held in a cloud key management service, so the repository contains ciphertext and only the cluster can read it. The history is safe, and reviewers can still see which keys changed.

Encrypt for one cluster. A sealed secret is encrypted with a public key whose private half never leaves the target, meaning the committed file is useless anywhere else.

Reference rather than store. An operator reads a pointer from the repository and fetches the real value from a managed secret store at run time. Nothing sensitive is ever committed, and rotation happens in the store without a commit at all.

Moving a Change Through Environments

Promotion becomes a merge. Staging tracks one directory or branch, production tracks another, and promoting means opening a pull request that copies the tested reference across.

The advantage is that the diff is exactly what will change, reviewed before it happens, with an approver recorded against it. For teams with compliance obligations, this is often the cheapest change control evidence they will ever produce.

Automated promotion is possible: a policy that opens the production pull request once staging has been healthy for a period. Keep a human on the merge button until the health signals have proven themselves, or you have simply automated the propagation of bad releases.

Where the Model Struggles

GitOps assumes a target that continuously reconciles. Kubernetes provides that natively. A handful of virtual machines does not, so applying the model there means running a periodic configuration management tool instead, which is a different arrangement with a similar spirit.

It also assumes changes can be expressed declaratively. Data migrations, one off backfills and anything with an ordering requirement sit awkwardly, and usually run as jobs triggered alongside rather than inside the reconciliation loop.

And it adds a component to operate. A cluster small enough that one person deploys with a command line tool may not get enough value to justify the agent, the repository layout and the secret encryption workflow.

If you are trying it, a managed Kubernetes service removes the hardest part of the prerequisite. The Civo account listings describe an account oriented around managed Kubernetes, and the Civo versus DigitalOcean comparison looks at how their cluster offerings differ. The infrastructure underneath the cluster is usually still defined with Terraform, which pairs with GitOps rather than competing with it.

If You Adopt One Thing First

  • Separate the application repository from the configuration repository.
  • Let an in cluster agent pull changes instead of handing outside systems cluster credentials.
  • Start with drift reporting only, then enable automatic sync once the reports are quiet.
  • Turn on pruning in non production first, behind branch protection.
  • Pick a secrets approach before the first real workload, not after.
  • Exclude fields that other controllers legitimately change from comparison.
  • Treat promotion as a reviewed merge, and keep a human on the production one.

Questions about a cloud account?

Ask about products, variants, availability or purchasing on either channel.