Eduard Tamsa

Eduard Tamsa

Software thinkerer

All articles

GitOps: Great Idea, Often Poorly Explained

GitOps is a good idea that is often explained as a collection of tools.

Install Argo CD. Put Kubernetes YAML in Git. Enable automatic synchronization. Now the team has GitOps.

That description is convenient, but it misses the part that actually matters. GitOps is not mainly about where YAML files live. It is about operating systems from a declared, reviewable source of truth and continuously reconciling reality with that declared state.

The tool is useful. The operating model is the real change.

Git Is Not the Goal

Git gives us several valuable properties: history, review, authorship, branching, and a clear record of what changed. Those properties make it a practical place to store desired state.

But moving configuration into a repository does not automatically create good operations.

If the repository contains copied resources nobody understands, secrets stored in plain text, environment-specific changes made directly in production, and pull requests approved without meaningful review, the team has not improved much. It has moved the confusion into Git.

The goal is to make the intended state explicit enough that both humans and automation can reason about it.

When somebody asks why a deployment looks a certain way, there should be a change that explains it. When the cluster drifts, the system should detect it. When a change is wrong, the team should have a reliable way to return to a known state.

Git helps make that possible. It is not the entire system.

Desired State Changes the Conversation

Traditional deployment instructions are usually imperative: run this command, then run another command, then check whether the service started. The result depends on the starting condition and on every step completing correctly.

GitOps works better when the team describes the result it wants.

The application should run this image. It should have this configuration. It should expose this service. It should have these resource limits. This policy should apply. The reconciler repeatedly compares that desired state with the real system and works to close the difference.

This is why reconciliation matters more than the deployment button. A pipeline that runs kubectl apply after a merge can be useful, but a reconciler adds continuous attention. It notices changes that happen after the pipeline finishes.

That includes accidental edits, emergency changes, failed updates, and resources that somebody created manually.

Drift Is a Signal

Many teams talk about drift as if it is only a technical nuisance. I think drift is also organizational information.

If engineers regularly change production directly, there is usually a reason. Maybe the GitOps path is too slow during incidents. Maybe the repository does not model an important setting. Maybe permissions are easier to obtain in the cluster than in the deployment workflow. Maybe people do not trust the reconciler.

Automatically overwriting every manual change without understanding this behavior can create a dangerous fight between humans and automation.

A better system makes drift visible, defines when self-healing is appropriate, and gives emergency work a documented path back into Git. If somebody must change production directly, that change should become a pull request or be deliberately reverted after the incident.

The source of truth stays true only when the operating process respects it.

Argo CD Is a Reconciler, Not a Strategy

Argo CD makes GitOps practical for Kubernetes. It watches repositories, compares desired resources with cluster state, displays differences, and can synchronize changes automatically.

That is powerful, but Argo CD cannot decide how a team should structure repositories, promote releases, separate environments, manage secrets, or approve risky changes.

Those decisions are part of the platform design.

For example, automatically synchronizing a development namespace may be low risk. Automatically applying a database migration in production is a different decision. Both can use Argo CD, but they should not necessarily use the same approval model.

The common mistake is enabling automation first and designing controls later. The better approach is to classify changes by impact and decide where human review belongs.

Rollback Is Not Always Revert

Git makes rollback look easy: revert the commit and let the reconciler apply the old state.

For stateless configuration, that can work well. For stateful systems, it may not.

An older application may not understand a newer database schema. A deleted persistent resource may not return with its data. A rotated secret may have already invalidated the previous credential. An external API change may not be reversible from Kubernetes manifests.

GitOps gives you a strong mechanism for restoring declared configuration. It does not remove the need to design application recovery.

Every production change still needs a realistic answer to a few questions: What state changes outside Git? Is the change backward compatible? How will data be recovered? What happens if the old version cannot run anymore?

The repository is a recovery tool, not a time machine.

A Better GitOps Workflow

A useful GitOps workflow is usually boring and clear:

  • Application and platform state is declared in a repository.
  • Changes arrive through small pull requests.
  • Automated checks validate syntax, policy, security, and expected behavior.
  • Reviewers can understand the operational impact.
  • A reconciler applies approved state and reports drift.
  • Direct production changes are restricted and audited.
  • Emergency changes have a path back into the source of truth.
  • Recovery is tested for both configuration and data.

None of these points requires a complicated platform. The important part is that the process forms a closed loop. A change is proposed, reviewed, applied, observed, and corrected through the same operating model.

Final Thought

GitOps is not “Kubernetes files in Git.” It is a discipline for making desired state explicit, changes reviewable, drift visible, and reconciliation continuous.

Argo CD and similar tools are valuable because they enforce part of that discipline at scale. But the tool cannot create ownership, good reviews, safe promotion, or a recovery strategy.

Use Git as the source of truth. Use reconciliation to keep systems close to it. Then design the human process so the source of truth remains trustworthy.

That is the great idea behind GitOps. The YAML is only the implementation detail.