A reliable GitOps workflow makes deployments easier to review, repeat, and audit by treating Git as the source of truth for application and infrastructure configuration. This guide provides a reusable checklist for structuring repositories, separating environments, approving changes, managing secrets, detecting drift, and rolling back safely.
Overview
GitOps is a delivery model in which desired system state is declared in version control and an automated mechanism works to make the running environment match that state. The model is commonly associated with Kubernetes, but the underlying practices also apply to infrastructure as code, cloud configuration, policy, and other deployment targets.
A GitOps workflow usually has four parts:
- Source repositories: Git repositories store application code, deployment manifests, infrastructure definitions, policies, and documentation.
- Continuous integration: CI systems build, test, scan, and package changes into versioned artifacts.
- Continuous delivery or reconciliation: An agent or deployment system observes the declared state and applies approved changes to an environment.
- Operational feedback: Logs, events, alerts, and deployment status show whether the desired state was applied successfully.
The key design decision is not which tool to select first. It is how to define ownership, promotion, approval, and recovery. A well-designed workflow should answer five questions for every change: where is it declared, who can approve it, which environment receives it, how is it verified, and how can it be reversed?
GitOps works best when repositories are understandable to both people and automation. Use consistent naming, keep configuration close to its ownership boundary, and document the path from a pull request to a production change. For broader delivery automation patterns, see the practical guide to DevOps workflow automation.
Checklist by scenario
Starting a new GitOps workflow
- Define the source of truth for application code, deployment configuration, infrastructure, and secrets references.
- Choose whether application code and environment configuration belong in separate repositories or separate directories with clear ownership.
- Document the path from commit to build, artifact publication, deployment, verification, and notification.
- Set branch protection and require review for changes that affect shared infrastructure or production.
- Give the reconciliation system the minimum permissions needed for its target environment.
- Begin with one service or non-production environment so the team can test the operating model before expanding it.
Structuring repositories
There is no single repository layout that fits every organization. The important property is a clear boundary between reusable definitions and environment-specific decisions.
A common arrangement uses one repository for application source and another for deployment configuration. The application repository contains source code, tests, container build instructions, and CI configuration. The configuration repository contains manifests, Helm values, Kustomize overlays, infrastructure modules, or equivalent declarations.
Within an environment repository, a structure might distinguish shared configuration from environment overlays:
- Base definitions: reusable deployment settings that should remain consistent across environments.
- Environment overlays: replica counts, resource limits, hostnames, feature flags, and integrations that differ between development, staging, and production.
- Policy and access configuration: rules that control what may run and who or what may change it.
- Operational documentation: ownership, dependencies, verification steps, and rollback notes.
Keep generated files out of the workflow unless they are intentionally reviewed and treated as authoritative. If a tool generates manifests, make the generation command reproducible and ensure reviewers can understand the resulting change.
Promoting changes across environments
Promotion should be explicit rather than dependent on an engineer copying values between files. A typical sequence is development, test or staging, and production, although the names and number of environments should reflect the system’s risk.
- Build an immutable artifact from a known source revision.
- Deploy that artifact to a lower environment through an automated change.
- Run automated tests and environment-specific checks.
- Update the next environment’s declaration to reference the same artifact version.
- Require the appropriate review before production promotion.
- Record deployment status, approvers, and verification results.
Promoting the same artifact reduces uncertainty. Rebuilding separately for each environment can introduce differences that are difficult to diagnose. Environment-specific behavior should usually be expressed through configuration, not by silently changing the artifact.
Managing pull requests and approvals
- Use small, focused pull requests for configuration changes.
- Explain the operational effect, expected risk, validation method, and rollback plan in the pull request description.
- Require ownership review for production, networking, identity, and shared platform changes.
- Run syntax checks, policy checks, manifest validation, security checks, and preview or diff commands before merge.
- Separate approval of a change from confirmation that it was successfully applied.
- Prevent direct production edits where practical, or document and reconcile any emergency exception afterward.
Reviewers should inspect the rendered or planned output, not only the source template. A small values change can produce a substantial deployment difference.
Handling secrets
GitOps does not mean placing plaintext credentials in Git. Store secret material in an approved secrets manager or use an encryption workflow that allows encrypted values to be safely versioned. The deployment system should retrieve or decrypt secrets at runtime without exposing them in pull requests, logs, rendered output, or shell history.
Before adopting a pattern, confirm how it handles key rotation, access revocation, audit records, backup, recovery, and local development. Keep secret references separate from ordinary configuration when that makes review and permission boundaries clearer. The guide to secrets management tools for DevOps can help frame that evaluation.
Planning rollback and recovery
A rollback should be a known Git change or a documented emergency procedure, not an improvised command remembered by one operator. Define whether rollback means reverting configuration, restoring a previous artifact, shifting traffic, or restoring data. These actions have different risks.
- Keep deployable artifact versions available for the required recovery period.
- Record the last known-good revision for each environment.
- Test rollback in a non-production environment.
- Document database compatibility and migration constraints.
- Define who can authorize an emergency rollback and how the event is recorded.
- After an emergency change, reconcile Git with the running state to prevent the next deployment from undoing the fix.
What to double-check
Drift detection
Drift occurs when the running environment differs from the declared state. It may result from a manual change, an external controller, a failed deployment, or a configuration source that GitOps does not manage. Decide which resources are authoritative in Git and which are intentionally managed elsewhere.
Check that the delivery system reports synchronization status, health status, and the specific difference between desired and actual state. Notifications should reach the people who own the service, not only a shared system channel. A drift alert without ownership or a response procedure quickly becomes background noise.
Auditability
For each production change, you should be able to connect the deployed state to a commit, pull request, artifact, approval, and deployment result. Keep these records available for the period your team needs to investigate incidents and operational changes. Auditability is strongest when the workflow produces evidence automatically rather than relying on manual notes.
Permissions and failure boundaries
Check repository permissions, CI credentials, deployment-agent permissions, cloud roles, and production access separately. A build process should not automatically receive broad production privileges merely because it creates an artifact. Use separate credentials and narrowly scoped roles where possible.
Also identify what happens when a dependency is unavailable. Can a deployment proceed if an image registry, secrets provider, policy service, or Git host is temporarily unreachable? Document whether the system fails closed, pauses reconciliation, or uses a previously approved state.
Observability and verification
A successful application of configuration does not necessarily mean the service is healthy. Pair deployment status with health checks, logs, metrics, synthetic checks, and application-level verification. Define what must be true before a promotion is considered complete and who responds when those checks fail.
Common mistakes
- Putting everything in one undifferentiated repository: A single repository can work, but unclear ownership and unrelated changes make review and permissions difficult. Use directories, ownership rules, and validation boundaries if you keep a monorepo.
- Using branches as permanent environments without a clear model: Long-lived environment branches can create merge drift. If branches represent environments, document promotion and synchronization rules; otherwise, use explicit overlays or configuration updates.
- Rebuilding artifacts during promotion: This weakens confidence that staging and production received the same software. Prefer immutable, traceable artifact versions.
- Allowing manual fixes to become invisible state: Emergency access may be necessary, but the resulting change should be reviewed, documented, and reconciled.
- Storing plaintext secrets in configuration: Repository access, pull request previews, logs, and caches can expose values. Use a suitable secret-handling design and test that sensitive values are masked.
- Automating deployment without automating validation: Faster application of an incorrect change is not safer delivery. Add schema, policy, security, and runtime checks appropriate to the service.
- Ignoring deletion and rename behavior: A change that removes a declaration may delete a live resource. Require reviewers to examine destructive diffs and define safeguards for high-impact resources.
- Making rollback depend on unavailable systems: If recovery requires a registry, key, or operator that is inaccessible during an incident, the procedure is not complete. Test dependencies and keep recovery instructions discoverable.
When to revisit
Review this GitOps workflow before seasonal planning cycles, after a significant incident, and whenever the team changes its repositories, CI/CD tools, deployment targets, secrets provider, or approval model. Revisit it before adopting a new environment, service class, cluster, cloud account, or infrastructure module.
Use the following short review at least periodically:
- Choose one recent production deployment and trace it from source commit to running artifact.
- Confirm that the pull request, approvals, checks, and deployment result are easy to find.
- Compare declared and actual state for representative resources.
- Perform a rollback exercise or tabletop review, including data and secret dependencies.
- Remove obsolete permissions, branches, repositories, environments, and credentials.
- Update ownership, runbooks, alerts, and onboarding documentation.
As the platform grows, compare the workflow against the team’s wider platform engineering tools stack and documentation practices. The goal is not to add more automation for its own sake. It is to make the safe path clear, repeatable, observable, and easy for the next engineer to understand.