GitOps as an operating model: starting with Flux
How we approach GitOps with Flux: state lives in the repository, reconciliation is understood instead of distrusted, secrets stay encrypted.
In most teams there are two truths about what runs on the systems: the one in the terminal of the last change, and the one in the documentation. GitOps is the decision to admit only one truth: the state in the repository. The controllers of the Flux family are the tools that enforce this decision on the system side, and getting started is smaller than the term suggests.
The model in one sentence
A controller on the cluster or server continuously compares the actual state with the state the repository describes and corrects deviations toward the repository. "I change live and write it down later" becomes "I change in the repository and the system follows". That is the whole core. From it follow behaviors that become tangible in operations: a manual change on the system disappears at the next reconciliation, not because a rule forbids it, but because the source of truth looks different. A merge into the configuration branch is the deployment. And whoever wants to know what runs where looks into a tree of files, not into the memory of three colleagues.
A structure for small teams
The most common starting mistake is building the repository the way a large enterprise would. For small environments a plain split has proven itself: one area for cluster or server definitions, one for applications, and inside it one layer per environment. The controller receives one root per environment from which it draws its working set. That keeps visible what applies in which environment, and rolling out into a second environment is a reference, not a relocation.
For applications that come from package sources, the Flux family ships ready connections that set versions from within the repository. What matters is less the concrete tool than the rule behind it: what gets deployed stands as a line in the repository, with version, source and purpose.
What ends up in those lines is decided on the image side; the rules live in the post Container image hygiene we follow.
What ends up in those lines is decided on the image side; the rules live in the post Container image hygiene we follow.
What ends up in those lines is decided on the image side; the rules live in the post Container image hygiene we follow.
Understanding reconciliation instead of distrusting it
The second common starting mistake is seeing automatic reconciliation as the enemy of flexibility. It is the opposite: it is the machine that enforces the state the team agreed on. The question is not "how do we outsmart the controller" but "which state should hold". Emergencies are the only legitimate exception state, and they run deliberately: manual change allowed, logging mandatory, and the return into the repository state the same day.
What reconciliation removes from daily work is the drift problem: servers and clusters change through updates, misconfigurations and well-meant interventions. A system that continuously reconciles its intended shape against the repository finds and fixes those deviations itself instead of them being discovered in an audit of three months past.
Secrets have no plaintext home in the repository
Once the state lives in the repository, the question arises what happens to credentials, tokens and certificates. The answer is firm: plaintext has no place there. Tools like SOPS encrypt exactly those files against a key list, so the repository carries the secrets as cipher and the decryption happens where the application runs. Key management thereby becomes part of operations, but the kind that gets built once properly, not the kind that generates work every day.
The starting point that holds
The path in is a single service. We deliberately choose a system small enough that a failure worries nobody, but representative enough that all the questions appear that matter later: what does the merge process look like? Who reviews changes? How do dependencies behave when two changes land simultaneously? Those questions get answered on the small service, not on the critical infrastructure.
What the model does to the review process
The most common objection to the operating model reads: every small change now goes through a merge, and that slows the work down. Practice answers with an inversion: the merge is not the slowdown, it is the agreement made visible that previously happened verbally or not at all. Small changes get small merges, and whoever can move them themselves moves them themselves; what remains is the agreement that previously lived in the hallway or in the retrospective.
The second effect concerns documentation, or rather its disappearance: a state that lives in the repository needs no separate documentation running alongside and aging. The manifests are the description; whoever can read them knows what holds. That replaces not every explanation, but it collects half the questions otherwise answered in onboarding conversations, and it guarantees the answer cannot be older than the actual state.
A word on the dependency on the tool belongs in the weighing, because the operating model ties the landscape to the controllers that enforce it. The way out of that binding is the same thing that creates it: the state lives in a Git repository, that is, in a format every comparable tool can read. A controller change is thereby a project of weeks, not a relocation into the unknown, and exactly that property makes the decision reversible. Whoever fears the binding to a specific tool as a risk should count the binding to the format as the counterweight, because it is what keeps the landscape portable.
From the first service the area grows organically: the second service, the shared foundations, finally the environments that were only hand-managed before. What stands at the end is not a grand work but a tree of files describing the same state the systems actually hold. If you want this operating model established for your environment, the CI/CD pipeline management page describes the matching service, and the contact page is the fastest way to reach us.
Sources
- Flux documentation, https://fluxcd.io/flux/ (accessed 2026-11-03)
- SOPS project, documentation and repository, https://github.com/getsops/sops (accessed 2026-11-03)