Skip to main content
DevOps7 min readSeptember 22, 2025

GitOps Workflow: Managing Infrastructure as Code

GitOps uses Git as the single source of truth for infrastructure and application deployments. Here's how to implement it without overcomplicating your pipeline.

James Ross Jr.
James Ross Jr.

Strategic Systems Architect & Enterprise Software Developer

GitOps Workflow: Managing Infrastructure as Code

GitOps is the practice of using Git as the single source of truth for both application code and infrastructure configuration. Every change to your system — whether it is a new feature, a scaling adjustment, or a security patch — flows through a Git commit, a pull request, and an automated reconciliation process.

The concept is straightforward, but implementing it well requires understanding how the pieces fit together and where teams commonly stumble.

The Core Principles

GitOps rests on four principles that distinguish it from traditional CI/CD.

First, the entire system is described declaratively. You do not write scripts that say "run these commands to set up the server." You write configuration that says "the system should look like this." The tooling figures out how to get from the current state to the desired state.

Second, the desired state is versioned in Git. Every configuration file, manifest, and policy lives in a repository. Git gives you version history, audit trails, branching for experiments, and pull requests for review. This is not optional or aspirational — it is the mechanism by which changes are proposed, reviewed, and applied.

Third, approved changes are applied automatically. Once a change is merged to the main branch, an automated agent detects the new desired state and applies it to the running system. There is no manual step between merge and deployment. This eliminates the "it was merged but nobody deployed it" problem that plagues teams with manual release processes.

Fourth, agents continuously verify that the running system matches the desired state. If someone makes a manual change to a server — an SSH session, a console click, a script run outside the pipeline — the agent detects the drift and either alerts or automatically corrects it. This is the property that makes GitOps fundamentally more reliable than imperative approaches.

These principles work well alongside feature flag architecture, where the deployment pipeline handles infrastructure while flags control feature availability.

Setting Up a GitOps Repository Structure

The repository structure depends on your scale, but a pattern that works well for most teams separates application code from deployment configuration.

Your application repository contains source code, tests, and a CI pipeline that builds container images and pushes them to a registry. Your deployment repository contains the Kubernetes manifests, Terraform configurations, or Docker Compose files that describe the running system. The application CI pipeline updates the deployment repository when a new image is built.

infrastructure/
 environments/
 production/
 app-config.yaml
 database.yaml
 networking.yaml
 staging/
 app-config.yaml
 database.yaml
 networking.yaml
 base/
 app/
 deployment.yaml
 service.yaml
 ingress.yaml
 database/
 statefulset.yaml
 service.yaml

The base directory contains templates, and each environment directory contains the overrides specific to that environment. Kustomize overlays or Helm values files handle the environment-specific differences.

Why separate repositories? Because the deployment cadence for infrastructure changes differs from application changes. A Terraform change to your VPC should go through a different review process than an application deployment. Separating the repositories gives you independent review flows, separate access controls, and cleaner audit trails.

Reconciliation and Drift Detection

The reconciliation loop is the heart of GitOps. A controller running in your cluster or on your infrastructure periodically compares the desired state in Git with the actual state of the running system. When they diverge, it takes action.

ArgoCD and Flux are the two dominant tools for Kubernetes-based GitOps. For non-Kubernetes infrastructure, Terraform Cloud and Atlantis provide similar workflows for infrastructure resources. The choice depends on your platform, but the principle is the same.

Configure your reconciliation interval based on your tolerance for drift. Most teams poll every three to five minutes, which is frequent enough to catch manual changes quickly without generating excessive API calls. Some tools support webhook-based triggers that initiate reconciliation immediately when a push to the deployment repository is detected.

Drift detection should be treated as a monitoring concern. When the controller detects that the running system does not match the desired state — whether from manual intervention, failed deployments, or external changes — it should emit metrics and alerts. This is separate from automatic correction. Some teams want automatic correction for all drift. Others prefer to alert and investigate, correcting manually for certain resource types. Configure this per-resource based on risk.

Managing container security is a natural complement to GitOps. When your security scanning is integrated into the same pipeline that manages your deployments, vulnerable images never reach production because the desired state in Git always reflects scanned, approved configurations.

Common Pitfalls and How to Avoid Them

The most common GitOps failure is secret management. Secrets should not live in Git, even encrypted. Use a secrets manager — HashiCorp Vault, AWS Secrets Manager, or Sealed Secrets for Kubernetes — and reference secrets by name in your Git-managed manifests. The reconciliation agent resolves secret references at apply time from the secrets manager. For a deeper treatment, see secrets management strategies.

The second pitfall is configuration sprawl. Teams start with clean, well-organized manifests and gradually accumulate one-off patches, temporary overrides, and environment-specific hacks. Combat this with regular audits of your deployment repository. If a configuration exists in only one environment with no explanation, it is either a mistake or an undocumented requirement — both need attention.

The third pitfall is treating GitOps as all-or-nothing. You do not need to migrate your entire infrastructure on day one. Start with one application in one environment. Get the workflow right — the pull request process, the review standards, the reconciliation monitoring. Then expand incrementally. Teams that attempt a full migration in a single sprint inevitably cut corners on the parts that matter most: monitoring, rollback procedures, and access controls.

GitOps works because it applies the same discipline to infrastructure that software teams already apply to application code. Version control, code review, automated testing, and continuous deployment are proven practices. Extending them to infrastructure is not a radical idea. It is the logical conclusion of treating your systems as software.