GitOps for cloud and DevOps is an operating model in which desired system state is declarative, durably versioned and continuously reconciled by software agents. A pull request can show intent and approval, but GitOps is more than storing YAML in Git. Teams need clear ownership of repositories, artifacts, reconciliation, secrets, emergency change, promotion, drift and production outcomes. The objective is a change system that is observable, repeatable and recoverable, not the elimination of judgment or operations work.
Use this guide with Edilec's GitOps cost and scaling guide, CI/CD foundations and CI/CD modernization checklist. GitOps is strongly associated with Kubernetes, but the principles can govern other declarative cloud resources when a reliable controller can compare desired and observed state. Do not force imperative or stateful operations into reconciliation merely to use the label.
Understand the GitOps control model
The OpenGitOps principles describe desired state as declarative, versioned and immutable, pulled automatically, and continuously reconciled. The OpenGitOps project provides the concise vendor-neutral definition. Declarative state says what should exist rather than a one-time sequence of commands. Durable versioning provides history and review. Pull-based agents reduce the need to expose production credentials to a central pipeline. Continuous reconciliation detects and corrects divergence after deployment.
Choose the boundary of desired state. Include application versions, configuration, policies, namespaces, infrastructure references and controller definitions that can be safely reconciled. Exclude secrets in plaintext, transient runtime data and operations whose repeated execution is unsafe. Define the authoritative artifact for each resource so Terraform, a platform API and a GitOps controller do not fight over it. Record ownership and reconciliation order for dependencies such as custom resources, operators and applications.
| GitOps element | Implementation decision | Evidence |
|---|---|---|
| Desired state | Which resources are declarative and authoritative? | Repository and ownership map |
| Artifact | Which immutable revision is promoted? | Digest, source and build provenance |
| Reconciler | Which identity may change each environment? | Scoped role and controller inventory |
| Policy | What must pass before promotion? | Review, test and admission results |
| Recovery | How are bad state and controller failure handled? | Revert and bootstrap exercises |
| Drift | Which differences are corrected or alerted? | Reconciliation status and exception register |
Design repositories and immutable artifacts
Organize repositories around ownership, change coupling and access. Separate application source from environment state when it simplifies authority, but avoid a maze of repositories no team can trace. Use bases and overlays carefully; generated output must remain inspectable. Protect main branches, require review from code owners, sign high-risk changes where appropriate and restrict workflow modification. Never store long-lived production secrets in commits, including encrypted values without a governed key and rotation model.

Promote the same built artifact by digest rather than rebuilding per environment. Attach source, dependency, test and build evidence. The current SLSA 1.2 specification defines provenance and incremental supply-chain assurances; use it as one input to artifact trust. Keep environment configuration separate from artifact identity. An automated image updater should create a visible, policy-checked change rather than silently tracking a mutable tag in production.
Configure reconciliation and dependency order
Controllers need explicit source, path, revision, interval, timeout, retry and health behavior. Flux core concepts explain reconciliation as ensuring observed state matches declarative desired state. Argo CD offers a comparable continuous-delivery model through its official documentation. Evaluate tools by tenancy, scale, policy, drift, secret integration, progressive delivery, observability, disaster recovery and team support, not interface preference alone.
Model dependencies so controllers do not repeatedly apply an application before its API, policy or data service is ready. Use readiness and health checks that reflect usable service, not only object existence. Set backoff and concurrency to avoid API overload. Decide whether drift is automatically corrected, alerted or temporarily tolerated by resource class. Manual production edits will be reverted by design; provide a documented way to suspend reconciliation for diagnosis and capture the eventual desired-state change.
Secure the GitOps supply and execution path
Threat-model source account compromise, malicious pull requests, workflow tampering, artifact substitution, controller takeover, excessive cloud permissions, secret leakage and untrusted manifests. Use phishing-resistant authentication for privileged maintainers where appropriate, least-privilege controller identities, protected branches, independent review for sensitive paths and admission policies that enforce runtime guardrails. Separate tenants or environments when one controller compromise would create unacceptable blast radius. Keep audit records outside the cluster it monitors.
Manage secrets through an external secret service, sealed workflow or another approved pattern with clear key ownership and rotation. A repository should reference secret identity rather than expose value. Constrain which registries, repositories and object kinds a controller accepts. Verify artifacts before deployment where the platform supports it. Scan manifests for dangerous privileges and public exposure, but recognize that static checks cannot prove runtime safety. Test denied deployments and expired credentials.
Promote, roll back and recover deliberately
Use pull requests to move an immutable revision through environment or cohort state. Define required tests and approvals based on consequence. Progressive delivery controllers can shift traffic or cohorts while measuring health, but the analysis metric and abort behavior need ownership. Database and message changes require expand-migrate-contract compatibility; reverting application manifests cannot undo destructive data change. Record rollback feasibility for every release and prefer forward recovery where state has moved irreversibly.
Practice bootstrap from a clean control plane. Retain repository, artifact, key, cluster and cloud access needed to reinstall controllers and reconcile state. Back up stateful data separately; Git describes configuration, not customer data. Test loss of Git hosting, registry, controller namespace and credentials. A pull-based system still depends on reachable sources, so define cache or continuity behavior. Ensure emergency change is committed back to desired state after stabilization.
| Operating signal | Meaning | Response |
|---|---|---|
| Reconciliation success and age | Controller can reach desired state | Investigate source, dependency or permission |
| Drift count by class | Manual or external change exists | Revert, approve exception or change ownership |
| Promotion lead time | Flow from approved artifact to environment | Remove queue or policy bottleneck |
| Rollback or abort success | Release guardrails work | Repair compatibility or analysis criteria |
| Controller saturation | Control plane is overloaded | Shard, tune interval or reduce scope |
| Bootstrap exercise result | Recovery path remains usable | Restore missing artifact, key or runbook |
Adopt GitOps in controlled increments
Start with one noncritical service and one environment. Establish repository ownership, controller identity, observability, secret reference, promotion and recovery. The Kubernetes guide to declarative object management explains core declarative workflows, but production adoption also needs policy and support. Add production only after teams can diagnose a failed reconciliation and bootstrap the controller. Then expand by coherent platform capability, not manifest count.
Measure change lead time, failed reconciliation, drift age, deployment failure, recovery, manual production access, policy denial and control-plane cost. Review whether developers can understand desired and observed state without platform specialists. Retire old deployment credentials and paths as adoption expands; parallel mechanisms create ambiguity. Maintain an exception process for resources that cannot be reconciled safely, with owner and expiry. GitOps maturity is operational confidence, not percentage of resources represented as YAML.
Define the platform-team contract. Application teams should know which fields they own, which policies are centrally enforced, how they request a new capability and who responds to reconciliation failure. Provide tested templates and sensible defaults without hiding generated state. Platform teams should measure developer task success and support demand, not repository count. A paved path succeeds when teams can understand and safely extend it, not when every change requires a platform ticket.
Handle shared cluster and multi-tenant boundaries carefully. Repository permission does not automatically equal runtime isolation. Namespace, network, workload identity, admission, resource quota, secret and custom-resource permissions must align with the tenancy model. Prevent one team's desired state from changing cluster-wide resources unless explicitly delegated. Test controller impersonation and cross-namespace references. Consider separate reconcilers or clusters where a shared control-plane identity creates unacceptable impact.
Treat observability configuration as desired state while protecting the observation path from the workload it measures. Monitor source fetch, artifact verification, apply result, health assessment, queue, controller resource use and API throttling. Correlate a deployed revision with application service indicators. A green synchronization status proves declared objects match; it does not prove customers can use the service. Release analysis should combine reconciliation health with journey, error and saturation evidence.
Define change windows and reconciliation behavior during incidents. Teams may need to freeze automated promotion while preserving correction of harmful drift, or suspend selected resources while diagnosing. Make those modes explicit and permissioned. After the incident, reconcile manual state, restore normal automation and review whether the desired state, policy or health assessment failed to represent the actual operational need.
Key takeaways
- Define authoritative declarative state and ownership before installing a controller.
- Promote immutable artifacts with visible provenance and environment configuration.
- Scope reconciler identity, secrets, accepted sources and resource kinds.
- Design dependency, drift, rollback and bootstrap behavior explicitly.
- Expand only after teams can diagnose reconciliation and recover the control plane.
Frequently asked questions
Does GitOps require Kubernetes? No, but it requires declarative state and a trustworthy reconciler; Kubernetes has the most mature ecosystem. Is Git the only source format? Git often provides the human workflow, while immutable OCI artifacts may carry desired state. Can engineers still access production? Yes for governed diagnosis or emergency work, with reconciliation suspended when necessary and changes recorded afterward. Does revert equal rollback? Only for compatible state; databases and external effects may need forward recovery. How often should reconciliation run? Fast enough for service and drift needs without overwhelming APIs; choose by resource class.
Conclusion
GitOps makes cloud change dependable when desired state, artifact trust, controller authority and operational recovery are designed as one control loop. Reviewable repositories are the start, while reconciliation, policy, observability and tested bootstrap make the model real. Adopt it where declarative control fits, preserve explicit exceptions and judge success by safer, faster recovery-aware change.