Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

GitOps / Helm / ArgoCD

Promoting Releases Across Environments with Kustomize or Helm

Environment promotion in GitOps means moving a tested version from dev to staging to production by changing files in git, not by redeploying. We design overlays with Kustomize or per-environment Helm values, and promote through pull requests with approvals and an easy rollback.

Key takeaways

  • Promotion is a git change: the same artefact moves forward, and only the version reference and environment values differ.
  • Keep one base and small overlays, so environments differ only where they should.
  • Never rebuild per environment. Promote the identical image or chart that passed testing.
  • Automate promotion to lower environments and gate production with review.
  • Rollback is reverting a commit, which is why the promotion path must be simple.

The problem with how most teams promote

In many organisations, “promotion” means running a pipeline again with a different target. The build is repeated, a slightly different image comes out, and staging is no longer a faithful rehearsal for production. Environment configuration lives partly in the pipeline, partly in a wiki, partly in someone’s head. When production fails and staging did not, nobody can say exactly what differed.

GitOps gives a cleaner model. Each environment is a place in git, and promotion is a change to that place. This page is the part of our GitOps, Helm, ArgoCD and Flux service that defines how releases move. It depends on a sound repository structure.

What good looks like

  • The same image digest or chart version runs in every environment on its way to production.
  • Environment differences are small, visible and reviewed: replica counts, hostnames, resource sizes, feature flags.
  • A pull request shows exactly what will change in a given environment.
  • Production approval is a deliberate step with named owners.
  • Reverting a bad release is a git revert, nothing more.

How it works in practice

Kustomize overlays

A base holds the shared definition. Overlays patch only what differs.

apps/payments/
  base/
    deployment.yaml
    service.yaml
    kustomization.yaml
  overlays/
    dev/kustomization.yaml
    staging/kustomization.yaml
    prod/kustomization.yaml

The production overlay pins the image and adjusts size:

# apps/payments/overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
images:
  - name: registry.example.com/payments/api
    newTag: "1.18.3"
replicas:
  - name: payments-api
    count: 6
patches:
  - path: resources-patch.yaml

Promotion then means changing newTag in the next environment’s file. You can confirm what will be applied with kustomize build apps/payments/overlays/prod before merging, and CI can run the same command on every pull request.

Helm values per environment

With a chart, each environment has a values file, and the controller combines the shared chart with the right one:

# ArgoCD Application (excerpt)
source:
  repoURL: https://github.com/acme/fleet-config.git
  path: charts/payments
  helm:
    valueFiles:
      - values.yaml
      - values-prod.yaml

In Flux the HelmRelease holds values inline or references a ConfigMap. Both patterns work, and the discipline is the same: shared defaults in one place, environment values minimal.

Automating the lower environments

A pipeline builds an image, pushes it, and then updates the dev overlay in the config repository, either by committing directly with a bot identity or by opening a pull request. Staging can follow automatically after dev checks pass. This is where the tags, digests and chart versions flow, linking to chart publishing and to your wider CI/CD pipeline.

Gating production

Production promotion is a pull request that changes only the production version reference. Branch protection requires review from the owning team, and CI posts the rendered diff. Some teams add a staging soak time: a check confirms the version has been healthy in staging for a set period before the pull request can merge. For higher risk changes, combine this with canary or blue-green delivery, so production promotion starts small and widens gradually.

Decisions and trade-offs

Automatic versus pull-request-based updates. Controller-driven image automation reduces tooling but writes to git from inside the cluster, which complicates audit and permissions. A pipeline that opens pull requests is more explicit. We lean towards the pipeline approach for production and accept either for lower environments.

Pin by tag or digest. Tags are readable; digests are immutable. We use tags in git for readability combined with registry tag immutability, or digests where supply chain assurance matters.

Per-environment clusters or namespaces. Separate clusters for production isolate failure and access but cost more. Namespaces on one cluster are cheaper but share a blast radius. Overlays work with either; the choice is covered in our multi-cluster work.

When this is overkill. A product with one production environment and a short-lived preview environment does not need a staged pipeline with soak gates. Start with two environments and add stages when releases begin to cause problems.

A worked promotion, step by step

Take a change to the payments-api image. The build pipeline publishes a new tag and opens a pull request that edits one line in the development overlay. It merges automatically once checks pass, and the controller deploys it within minutes. A scheduled or manual job then opens a second pull request that copies the same tag into staging. Staging runs its smoke tests and soaks for an agreed period. Only then is a third pull request raised for production, assigned to the code owners of that folder.

Each pull request contains a one-line diff, which is what makes review meaningful. Reviewers see exactly which version moves, can check the staging result linked in the description, and approve knowing that rollback is a revert of the same commit. Compare this with promotion by rebuilding: the artefact that reaches production is never the one that was tested.

Promoting config as well as images

Image tags are the easy part. Config changes, such as a new feature flag default or a changed resource limit, should travel the same road. We keep the base identical across environments and let overlays hold only deliberate differences, then review those differences regularly. A quick way to spot accidental divergence is to render both overlays and compare them:

kustomize build overlays/staging > /tmp/staging.yaml
kustomize build overlays/production > /tmp/production.yaml
diff /tmp/staging.yaml /tmp/production.yaml

Anything in that diff should be explainable: replica counts, hostnames, resource sizes, external endpoints. Anything else is drift waiting to cause a surprise on release day.

Common failure modes

  • Rebuilding per environment. Breaks the promise that staging mirrors production. Fixed by building once.
  • Overlays that copy whole files. They drift. Keep patches small.
  • Secrets differing silently. Environment secrets come from a managed source such as Sealed Secrets or External Secrets Operator, with the same structure in every environment.
  • Skipped staging under pressure. Hotfix paths are defined in advance, with fewer steps but still reviewed.
  • Config changes and code changes in one release. Separating them makes failures easier to diagnose.

Delivery and handover

We deliver the base and overlay structure, the pipeline that updates lower environments, the pull request workflow for production, and CI checks that render and validate every environment. We also run a rehearsal in which your team promotes a real change and rolls it back.

How to tell it is working

Production releases are boring: a small pull request, a visible diff, a clean sync. Staging reliably predicts production. A rollback takes minutes and does not need a meeting. If you would like us to review your current release path, contact us.

References

How we deliver it

  1. 01

    Map environments

    We document which environments exist, what differs between them, and what must stay identical.

  2. 02

    Choose the mechanism

    Kustomize overlays, Helm values files, or a mix, chosen for how much your environments really differ.

  3. 03

    Build base and overlays

    Shared config lives in a base; each environment holds only its own patches, replicas, hosts and limits.

  4. 04

    Automate lower promotion

    A pipeline updates the image tag or chart version in the dev overlay after a successful build, and opens pull requests onward.

  5. 05

    Gate production

    Production changes need review, may require passing checks in staging, and can be scheduled or approved by named owners.

  6. 06

    Prove rollback

    We test reverting a promotion end to end so the team trusts it before they need it.

Tools and technologies

KustomizeHelmArgoCDFluxArgo CD Image UpdaterFlux image automationGitHub ActionsGitLab CIRenovateyq

Frequently asked questions

Kustomize overlays or Helm values for environments?
If you deploy plain manifests or a single chart with modest differences, either works. Kustomize overlays make differences explicit as patches against a shared base. Helm values files are simpler when the chart already parameterises everything. Many teams combine them: Helm for packaging, a values file per environment, and Kustomize for last-mile patches.
How do we promote from staging to production?
Change the version reference in the production folder through a pull request. That might be copying the image tag that is already running in staging. The pull request is the approval point, with required reviewers and checks. After merge, the GitOps controller applies it. Nothing is rebuilt, so what ran in staging is what runs in production.
Should dev update automatically?
Usually yes. Letting a successful build update the dev environment gives fast feedback and keeps people honest about main being deployable. Staging can also be automatic. Production should normally require a human approval, unless you have strong automated verification and a mature progressive delivery setup.
Can image updates be automated inside the cluster?
Yes. Flux has image automation controllers and ArgoCD has Image Updater, both of which can write new tags back to git. We often prefer the pipeline to open the pull request instead, because it is easier to audit and works the same across tools. We choose based on your preference for control versus convenience.
How do we avoid environments drifting apart?
Keep a single base, make overlays small, and review any new difference deliberately. Add a CI job that renders every environment and shows a diff against the others for the same release. Unexplained differences stand out. Long-lived copies of whole manifests per environment are the usual cause of drift.

Talk to an engineer about gitops environment promotion

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.