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

Kubernetes Consulting

GitOps for Kubernetes: Setting Up Argo CD or Flux the Practical Way

GitOps means your Git repository declares what runs in each cluster, and a controller (Argo CD or Flux) continuously makes the cluster match it. We design the repository layout, install and secure the controller, wire in your pipeline and secrets, and prove that rollback and drift detection work.

Key takeaways

  • Git becomes the audit trail: every change to a cluster is a reviewed, revertible commit.
  • CI builds and tests images, GitOps deploys them, and the two are deliberately separated.
  • Argo CD offers a rich UI and application model, Flux is lighter and more toolkit-like, and both are mature.
  • Repository structure and secrets handling are where GitOps projects succeed or struggle.
  • GitOps is not a fit for everything, and some workloads still need progressive delivery on top.

The problem GitOps removes

Without it, the real state of a cluster lives in the memory of whoever last ran kubectl apply. Staging and production drift apart. A hotfix applied during an incident is never committed. A pipeline holds cluster-admin credentials, so a compromised CI runner is a compromised cluster.

GitOps deployment on Kubernetes fixes this by inverting the direction. Instead of CI pushing changes into the cluster, a controller inside the cluster pulls from Git and reconciles. The GitOps principle is simple, and doing it well takes decisions about structure, secrets and promotion. We make these as part of our Kubernetes consulting work, with the wider approach in our GitOps, Helm, Argo CD and Flux service.

What good looks like

  • Every deployed resource is traceable to a commit and a reviewer.
  • The cluster cannot silently differ from Git. Drift is corrected or alerted.
  • Rolling back is a revert, and it works on a bad day.
  • CI has no standing credentials for production clusters.
  • Adding a service or environment follows a documented pattern, not tribal knowledge.

Argo CD or Flux

Both reconcile Git to a cluster, and both are widely used in production. The differences are of style.

AspectArgo CDFlux
InterfaceWeb UI, CLICLI and CRDs, optional UIs
Core modelApplication and ApplicationSetGitRepository, Kustomization, HelmRelease
Multi-clusterOne instance can manage manyUsually a controller per cluster
Image automationVia separate toolingBuilt-in image automation controllers
Learning curveGentle, visualSteeper but consistent

If your developers want to see sync status and logs in a browser, Argo CD is often the more welcoming choice. If you want minimal footprint and everything as Kubernetes objects, Flux fits. Our GitOps with Argo CD on EKS tutorial walks through one implementation.

Repository structure that survives growth

Structure matters more than the tool. We usually separate application source from deployment configuration, then organise the config repository by environment with a shared base:

platform-config/
  apps/
    api/
      base/            # Deployment, Service, config
      overlays/
        dev/
        staging/
        production/
  clusters/
    dev/               # Which apps run in dev cluster
    production/
  infrastructure/      # ingress, cert-manager, monitoring

An Argo CD application pointing at one overlay looks like:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api-production
  namespace: argocd
spec:
  project: production
  source:
    repoURL: https://github.com/example-org/platform-config.git
    targetRevision: main
    path: apps/api/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: api
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Automated sync with selfHeal makes Git authoritative. Many teams keep production on manual sync approval at first and move to automation as confidence grows. The environment overlay model is the same one we use to keep dev, staging and production consistent.

Promotion and CI integration

The healthy flow: CI builds an image tagged with the commit and scans it; a pipeline step opens a pull request (or commits) that updates the image reference in the dev overlay; the controller deploys it; promotion to staging and production is another reviewed change that moves the same image digest. Environment differences live in overlays, never in rebuilt images. See our CI/CD pipeline work and the pipeline best practices guide for the build side.

Migrating an existing cluster without a big bang

Most teams adopt GitOps on clusters that already run production traffic, so the migration order matters. We export the live manifests of one low-risk service, clean out generated fields such as status and managed metadata, and commit them to the config repository. The controller is then pointed at that path in a manual-sync mode, and we compare the diff it reports. A clean diff means Git now describes reality.

Only then do we switch on automated sync for that service. Repeating this service by service is slower than a single cutover, but a failed sync affects one workload, not the whole platform. Services with unusual lifecycles, such as jobs and operators that own their own resources, are left until last and often need ignore rules for fields that other controllers legitimately change.

Secrets

The first question every GitOps design must answer. Options:

  • Sealed Secrets: encrypt with a cluster key, commit the sealed object. Simple, but tied to that cluster’s key.
  • SOPS: encrypt files in Git with a cloud KMS key. Flexible, good for Flux and Argo CD plugins.
  • External Secrets Operator: reference secrets stored in a cloud secrets manager. Best when rotation and central storage matter.

We choose one pattern per organisation. Mixed approaches become hard to audit.

Trade-offs and when GitOps is not enough

  • Progressive delivery: a GitOps controller applies manifests. Canary and blue-green analysis need Argo Rollouts or Flagger on top.
  • Stateful migrations: database schema changes do not revert with Git. Plan them as separate, backwards compatible steps.
  • Small teams: for one service on one cluster, a simple pipeline may be enough. GitOps pays back as environments and teams multiply.
  • Emergency access: you still need a break-glass path, and a rule that anything changed by hand is committed afterwards.
  • Controller as critical infrastructure: if the controller breaks, deployments stop. Back it up, monitor it and know how to bootstrap it again from Terraform.

Common failure modes

  • Putting generated manifests and hand-written values in the same files, causing merge conflicts.
  • A single giant Application, so one error blocks every service.
  • Allowing prune without understanding it, then deleting a shared resource.
  • Controllers with cluster-admin used by every team, bypassing RBAC design. Use projects or tenants to scope what each team can deploy.
  • Ignoring sync failures because nobody is alerted.

Delivery and how to tell it works

We hand over the bootstrapped controller as code, the repository layout with templates for new services, a secrets pattern, alerts on failed or out-of-sync applications, and a rehearsed rollback. You will know it works when a deploy is a merged pull request, a manual change to the cluster is flagged or reverted within minutes, and a new engineer can ship a change on their first week. For help designing yours, book a consultation.

References

How we deliver it

  1. 01

    Assess current deployment

    We map how releases happen today, who has cluster access and where configuration lives.

  2. 02

    Pick the controller

    We compare Argo CD and Flux against your team, UI needs, multi-cluster plans and tenant model.

  3. 03

    Design the repository model

    Layout, environment overlays, app-of-apps or Kustomization structure and promotion flow are agreed.

  4. 04

    Install and secure

    The controller is bootstrapped by Terraform, with SSO, scoped permissions and sealed or external secrets.

  5. 05

    Migrate services in waves

    Non-critical services move first; production follows once rollback and drift handling are proven.

  6. 06

    Connect CI and observability

    Pipelines update image versions in Git, and sync status and alerts feed your monitoring.

Tools and technologies

Argo CDFluxHelmKustomizeArgo RolloutsFlaggerSealed SecretsExternal Secrets OperatorSOPSGitHub ActionsGitLab CITerraform

Frequently asked questions

What is GitOps in simple terms?
It is a way of operating infrastructure where Git holds the desired state and an automated agent in the cluster continuously reconciles reality to match it. Deployments become pull requests, history is the audit log, and a rollback is a revert. Manual kubectl changes are detected and corrected.
Argo CD or Flux, which is better?
Neither wins universally. Argo CD has a strong web UI, an Application abstraction and easy multi-cluster visibility, which many teams like. Flux is modular, Kubernetes-native and lighter, and fits teams preferring everything as CRDs and CLI. We choose based on your team's habits and tenancy needs.
Does GitOps replace our CI pipeline?
No. CI still builds, tests and scans images. GitOps handles delivery: CI pushes an image, then updates a version in Git, and the controller applies it. Keeping the cluster credentials out of CI is a security benefit, since the cluster pulls changes rather than being pushed to.
How do we handle secrets in GitOps?
Never commit plain secrets. Options include Sealed Secrets, SOPS encryption in Git, or the External Secrets Operator pulling from a cloud secrets manager. The best fit depends on rotation needs and where you already store secrets. We pick one and standardise it.
Should we use one repository or several?
A common pattern is separate repositories for application code and for deployment configuration, so releases do not require code changes and access can differ. Within the config repo, directories per environment work well. Very small teams can start with one repo and split later.
What if a deployment fails in production?
The controller reports the sync as degraded, and you revert the commit or use progressive delivery to halt the rollout automatically. Reverting in Git restores the previous state with a full audit trail. Database migrations are the exception and need their own rollback plan.

Talk to an engineer about gitops deployment kubernetes argocd

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.