Skip to content

GitOps Kubernetes Delivery Platform

ArgoCD + Helm with promotion by pull request

Production experience — sanitized case studyImplemented & validated locally

Basis: CV: standardized Helm-based deployment patterns and GitOps workflows with ArgoCD across dev, staging and production, with drift detection. The published code is a reference implementation of that pattern — all names and values are synthetic.

Overview

CI builds and signs images; a separate config repository holds the desired state per environment; ArgoCD reconciles clusters to it, detects drift, and rolls back by reverting a commit.

Problem

Push-based pipelines that run kubectl against clusters hold cluster credentials in CI, make the live state hard to audit and let manual changes drift unnoticed.

Solution

Pull-based delivery: clusters pull from Git, so CI never needs cluster credentials. Promotion is a pull request that bumps an image tag in the next environment's values file.

Architecture

  1. App repo CI

    • Test + build

      immutable SHA tag

    • Promotion PR

      bumps envs/dev image tag

  2. Config repo (desired state)

    • charts/orders-api

    • envs/dev · staging · prod

    • AppProject + ApplicationSet

  3. Argo CD

    • dev

      auto sync, self-heal, prune

    • staging

      auto sync, no prune

    • prod

      manual sync, deny windows

  4. Prod delivery

    • Argo Rollouts canary

      10% → analysis → 50% → 100%

    • AnalysisTemplate

      success rate ≥ 99%

    • External Secrets

      from Secrets Manager

CI writes to Git; Argo CD is the only thing that writes to clusters.

Failure and recovery path

  1. A canary whose success rate drops below 99% — or reports no data — fails analysis and the rollout aborts back to the stable version.
  2. A manual kubectl change shows up as drift; dev and staging self-heal it, prod surfaces it for review.
  3. Rollback is a git revert of the promotion commit; Argo Rollouts abort/undo covers an in-flight canary.
  4. An emergency hotfix can skip an environment only with an explicit flag, and the commit records why.

Technology stack

  • Argo CD
  • ApplicationSet
  • Argo Rollouts
  • Helm
  • External Secrets Operator
  • GitHub Actions
  • Prometheus analysis
  • kubeconform

Implementation

  • An ApplicationSet generates one Application per environment directory with per-environment sync policy; a new environment defaults to manual sync.
  • promote.py moves an image tag to the next environment by editing only the tag line, refuses mutable tags and skipped environments, and writes hotfix trailers into the commit message.
  • A drift report compares live and desired manifests, honouring the same ignoreDifferences Argo CD uses (HPA-managed replicas, status, managed fields).
  • A GitOps policy check: no automated sync or prune in prod, no cluster-scoped resources for the app project, no 'latest' tags, canary analysis wired for prod, and a minute-by-minute simulation proving the prod deny windows cover every off-hours minute.
  • kubeconform -strict validates every environment render and all Argo CD and Rollouts resources against their CRD schemas; 85 unit tests; the example CI workflow passes the repository's hardening linter.

Security

  • CI never holds cluster credentials; it can only open pull requests against the config repo.
  • The app's AppProject allows no cluster-scoped resources and only its own namespaces; namespaces and secret stores live in a separate platform project.
  • No plaintext secrets in Git: External Secrets pulls from Secrets Manager using workload identity.
  • The chart refuses missing or mutable image tags at render time.

Reliability

  • Production canary analysis runs only against canary pods, so the stable version's traffic cannot mask a bad release.
  • Sync windows block automated changes to prod outside business hours.

Cost

  • Argo CD and Rollouts run in-cluster and are cheap; the cost is operational — keep one Argo CD per trust boundary (see the cost doc).

Results

No quantified results are published for this project. Figures from client work are confidential, and this portfolio only shows numbers that can be verified or reproduced.

Code & documentation

Lessons learned

  • Keep application code and deployment config in separate repositories, or promotion PRs get noisy.
  • Enforce the delivery rules with a policy check in CI, not only in reviewers' heads.
  • Known gaps, stated in the README: nothing was installed into a cluster, canary weights follow pod ratio without a traffic router, and one upstream CRD schema needed a documented repair to validate.