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

CI/CD Pipelines

Kubernetes Deployment from CI/CD with Helm or Argo CD

Kubernetes deployment from CI/CD can be push-based, where the pipeline runs helm upgrade against the cluster, or pull-based, where CI updates a Git repository and Argo CD syncs it. We pick based on your team size, audit needs and cluster access model, and package workloads as versioned Helm charts either way.

Key takeaways

  • Helm packages and templates; Argo CD continuously reconciles. They are complementary, not competitors.
  • Push deploys are simpler to start with. Pull-based GitOps gives drift correction, audit history and no cluster credentials in CI.
  • CI builds and tests the image, then changes a version in Git or invokes Helm. It should not hold broad cluster admin rights.
  • Environment differences belong in values files, not in separate charts.
  • Whatever the model, deploys use immutable image digests and have a tested rollback.

From a passing build to a running pod

A pipeline is only valuable once its output reaches the cluster reliably. Many teams get as far as “the image is built” and then deploy with a script on someone’s laptop, a kubectl apply of hand-edited YAML, or a long-lived cluster admin kubeconfig stored in CI. These approaches work until a person is on holiday, a cluster is rebuilt, or an auditor asks who changed what.

This page covers how we connect CI/CD pipelines to Kubernetes using Helm, Argo CD or both, and how to decide between the two main models.

Two models: push and pull

Push-based deployment. The pipeline holds credentials, connects to the cluster and runs helm upgrade --install. It is easy to understand and quick to set up. The pipeline needs network access and permissions to the cluster, which makes it a high-value target. Drift is not corrected: if someone edits a resource by hand, nothing notices.

Pull-based deployment (GitOps). The pipeline never touches the cluster. It builds the image and commits the new version to a configuration repository. A controller in the cluster, such as Argo CD or Flux, notices the change and applies it. Git becomes the source of truth, and the controller reverts manual changes. See GitOps for the concept in more detail.

AspectPush (Helm from CI)Pull (Argo CD)
Setup effortLowModerate
Cluster credentials in CIRequiredNot required
Drift correctionNoneContinuous
Audit trailPipeline logsGit history
Multi-cluster at scaleGets awkwardDesigned for it
Extra component to runNoYes

We do not favour GitOps as dogma. For one cluster, one team and a handful of services, push with Helm and a tightly scoped role is perfectly sound. Pull earns its keep with multiple clusters, several teams, compliance requirements, or a history of drift problems. Our GitOps service goes deeper on that path, and the Argo CD on EKS tutorial shows a working setup.

Structuring Helm charts

A Helm chart bundles templates for Deployments, Services, Ingress and so on, with configuration supplied through values. The structure that causes least pain:

  • One chart per service, or one shared base chart that many services use with different values. Shared charts reduce duplication but tie services to one release cadence, so version the chart.
  • Per-environment values files (values-staging.yaml, values-production.yaml) layered over defaults. Environments differ in values, not in templates.
  • Sensible defaults for safety: resource requests and limits, readiness and liveness probes, a PodDisruptionBudget and a non-root security context.
  • Lint and test in CI: helm lint, helm template piped to a schema validator such as kubeconform, and optionally unit tests for templates.
# values-production.yaml
image:
  repository: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/checkout
  digest: sha256:REPLACED_BY_PIPELINE
replicaCount: 4
resources:
  requests: { cpu: 250m, memory: 256Mi }
  limits: { memory: 512Mi }

The digest value is filled in by the pipeline when it promotes a build. A real digest is a 64-character hash, so the placeholder above is only a marker for illustration.

Push deployment with guardrails

If you choose push, the pipeline should deploy like this:

helm upgrade --install checkout ./charts/checkout \
  --namespace shop \
  --values charts/checkout/values-production.yaml \
  --set image.digest="$IMAGE_DIGEST" \
  --atomic --timeout 5m

with the following protections around it: credentials obtained by OIDC and mapped to a Kubernetes role limited to the namespace, the job gated by a protected environment, and the --atomic flag to revert a failed upgrade. Namespaced roles matter. A pipeline that can only touch shop cannot damage the rest of the cluster, whereas one with cluster-admin can.

Pull deployment with Argo CD

With Argo CD, an Application declares which repository path should be synced to which cluster and namespace:

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

selfHeal reverts manual changes and prune removes resources deleted from Git. For production we sometimes turn automated sync off and keep a manual sync step as the approval, which fits with promotion gates. For many services and clusters we use ApplicationSet to generate Applications from a template rather than hand-writing each.

The CI side is then small: after the image is pushed, a job updates the tag or digest in the configuration repository (directly for dev, through a pull request for production). The pull request itself is the approval.

Handling the awkward parts

Database migrations. Run them as a Helm hook or an Argo CD pre-sync job, and write them to be backward-compatible so a rollback is possible. See automated rollback.

Secrets. Never commit plaintext. Use an operator that syncs from your secret store or an encrypted-in-Git approach, covered in secrets management.

Ordering. Use sync waves or hooks when resources depend on each other, for example CRDs before the resources that use them.

Config repository layout. A separate repository for deployment configuration keeps application commits and deploy commits apart, and permits different review rules. A monorepo of both is simpler for small teams.

Decisions and trade-offs

Helm versus Kustomize. Helm is better for distributing configurable packages and has a broad ecosystem. Kustomize is simpler for patching plain manifests and has no templating language. Many teams use Helm for third-party software and either for their own.

Argo CD versus Flux. Both implement GitOps well. Argo CD offers a UI that developers appreciate, and Flux is lighter and more composable. We choose by team preference rather than ideology.

When not to adopt GitOps. If your team has two engineers, one cluster and rare deploys, the controller, repository structure and extra concepts may cost more than they save.

Common failure modes

  • Cluster-admin kubeconfig stored in CI.
  • Mutable tags causing nodes to run different versions of the same tag.
  • Charts with no resource limits or probes.
  • Manual kubectl edit in production that GitOps then reverts, surprising the person who made it.
  • Rollback in the cluster only, immediately undone by the controller.
  • One giant values file for all environments.

Delivery and handover

We agree the model, build charts or review yours, wire CI to deployment, and install and configure Argo CD if chosen. Everything is stored in your repositories, and the Kubernetes side often links with our Kubernetes consulting work. You receive an architecture diagram, a how-to for adding a service, and a rehearsed promotion and rollback.

How to tell it is working

Look at deployment frequency, lead time from merge to running in production, the proportion of deploys that need manual intervention, drift detected and corrected, and time to restore after a bad release. If a new service can go live by adding a values file and an Application, and nobody needs cluster credentials on their laptop to ship, the model is working. To discuss which fits your team, book a consultation.

References

How we deliver it

  1. 01

    Choose push or pull

    We assess team size, number of clusters, compliance needs and who must be able to change what, then recommend a model with reasons.

  2. 02

    Structure the charts

    A chart per service, or a shared base chart, with sensible defaults and per-environment values files.

  3. 03

    Wire CI to deployment

    CI builds, tests and publishes the image, then either runs a gated Helm upgrade or commits the new version to the config repository.

  4. 04

    Install and configure Argo CD

    For pull-based flows, we set up Applications or ApplicationSets, projects, sync policies and access control.

  5. 05

    Add checks and progressive delivery

    Health checks, sync waves, hooks for migrations, and optionally canary rollouts guard each release.

  6. 06

    Document promotion and rollback

    Teams get a clear path for promoting between environments and a rehearsed route back to a previous release.

Tools and technologies

HelmArgo CDFluxKustomizekubectlArgo RolloutsGitHub ActionsGitLab CIHelm unittestkubeconformRenovate

Frequently asked questions

Should we use Helm, Argo CD or both?
They do different jobs. Helm packages Kubernetes manifests into versioned, configurable charts. Argo CD watches a Git repository and keeps the cluster matching it. Many teams use both: Helm charts as the packaging format, Argo CD as the delivery mechanism. A small team can start with Helm alone.
What is the difference between push and pull deployment?
In push, the CI pipeline connects to the cluster and applies changes. In pull, an agent inside the cluster, such as Argo CD or Flux, fetches desired state from Git and applies it. Pull means CI needs no cluster credentials and drift is corrected automatically, at the cost of running an extra controller.
How does CI update the version in a GitOps setup?
After publishing an image, CI commits the new tag or digest to the configuration repository, either directly for lower environments or through a pull request for production. Argo CD detects the change and syncs. Tools like Renovate or Argo CD Image Updater can also automate the bump.
Does Argo CD replace our CI pipeline?
No. Argo CD handles delivery to the cluster only. You still need CI to run tests, build and scan images and publish artefacts. The two connect through Git: CI produces a version, and Argo CD deploys what the repository says.
How do you roll back a Helm or Argo CD deployment?
With Helm, helm rollback restores a prior release revision. With Argo CD, the cleanest rollback is reverting the commit in Git, which is audited and stays consistent with the controller. Argo CD can also sync to an earlier revision manually, but it will then show as out of sync with Git.

Talk to an engineer about kubernetes deployment helm 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.