Helm Release Management
Helm treats every deployment as a versioned, tracked, and reversible release. Unlike raw kubectl apply, Helm maintains a full revision history of what was deployed, enabling atomic upgrades, instant rollbacks, and auditable change tracking. Synthesized from Helm Zero to Hero by @AbhishekVeeramalla.
The Release Lifecycle
A Helm release moves through four states: Install → Upgrade → Rollback → Uninstall. Every transition creates a revision snapshot, stored as a Secret (default in Helm v3) in the release’s Namespace.
Install (rev 1) → Upgrade (rev 2) → Upgrade (rev 3) → Rollback (rev 4 = copy of rev 2)
Revision numbers only increase. A rollback does not delete the bad revision — it creates a new revision that re-applies the manifest state of an earlier one. This preserves a complete, immutable audit trail.
Installing a Release
# Basic install from a repository
helm install my-nginx bitnami/nginx
# Install into a specific Namespace (creates the Namespace if needed)
helm install my-nginx bitnami/nginx -n web --create-namespace
# Install with custom values
helm install my-nginx bitnami/nginx --set service.type=NodePort
helm install my-nginx bitnami/nginx -f prod-values.yaml
# Install with a generated name
helm install bitnami/nginx --generate-name
# Dry-run to validate without deploying
helm install my-nginx bitnami/nginx --dry-runKey behaviors:
- Release names must be unique per Namespace. You can have
my-nginxin bothdevandprodNamespaces. helm installis atomic by default: if the deployment fails (e.g., Pods never become ready), Helm automatically rolls back to the pre-install state.- The
--waitflag blocks until all resources reach a ready state (respecting readiness probes).
Upgrading a Release
# Upgrade to a new chart version
helm upgrade my-nginx bitnami/nginx --version 14.0.0
# Upgrade with new values
helm upgrade my-nginx bitnami/nginx --set replicaCount=5
# Upgrade or install if not present (CI/CD standard)
helm upgrade --install my-nginx bitnami/nginx
# Force resource recreation (e.g., immutable field changes)
helm upgrade my-nginx bitnami/nginx --force
# Atomic upgrade: rollback automatically on failure
helm upgrade my-nginx bitnami/nginx --atomicUpgrade mechanics:
- Helm computes a three-way strategic merge between the previous release manifest, the live cluster state, and the new manifest. This handles out-of-band edits (e.g., someone
kubectl edita Deployment) gracefully. - Every upgrade creates a new revision. Previous revisions remain in history.
- The
--atomicflag is recommended in CI/CD: if the upgrade fails, Helm rolls back automatically rather than leaving the cluster in a broken intermediate state.
Rollback
Rollback is Helm’s safety net — the feature that distinguishes it from plain kubectl apply:
# View revision history
helm history my-nginx
# Rollback to revision 2
helm rollback my-nginx 2
# Rollback with a timeout
helm rollback my-nginx 2 --wait --timeout 5mWhat happens during rollback:
- Helm reads the manifest stored for the target revision
- It re-applies that manifest to the cluster
- A new revision is created (e.g., rev 5 = copy of rev 2)
- The live cluster state is restored to the target revision’s configuration
Important: Rollback restores Kubernetes resource state, not application data. If a database schema migration ran during an upgrade, rolling back the Deployment does not reverse the migration. Data rollbacks require application-level strategies.
Uninstalling a Release
# Remove all resources created by the release
helm uninstall my-nginx
# Remove but preserve release history
helm uninstall my-nginx --keep-history
# Uninstall from a specific Namespace
helm uninstall my-nginx -n webBy default, helm uninstall deletes all tracked resources and removes the release history. With --keep-history, the release is marked as uninstalled but revision Secrets are retained for audit purposes.
Release History and Audit
# List all revisions of a release
helm history my-nginx
# Output format: revision, updated, status, chart, app version, description
# REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
# 1 Mon Jul 14 10:00:00 deployed nginx-13.0.0 1.27.0 Install complete
# 2 Mon Jul 14 11:30:00 deployed nginx-13.1.0 1.28.0 Upgrade complete
# 3 Mon Jul 14 12:00:00 failed nginx-13.1.0 1.28.0 Upgrade "my-nginx" failed
# 4 Mon Jul 14 12:05:00 deployed nginx-13.0.0 1.27.0 Rollback to 1Revision statuses:
| Status | Meaning |
|---|---|
deployed | Successfully applied and healthy |
superseded | Replaced by a newer revision |
failed | Deployment failed (may have auto-rolled back) |
uninstalled | Release was removed |
pending-install | Installation in progress |
pending-upgrade | Upgrade in progress |
pending-rollback | Rollback in progress |
Release Storage: Secrets vs ConfigMaps
Helm v3 stores release metadata in the target Namespace. The default storage backend is Secrets (helm.sh/release.v1 type). This is more secure than the Helm v2 ConfigMap default because:
- Secrets are base64-encoded at rest (minimal obfuscation, but better than plaintext)
- RBAC can restrict read access to release history
- etcd encryption at rest (if enabled) applies to Secrets
To use ConfigMaps instead (legacy behavior):
helm install my-nginx bitnami/nginx --storage-driver configmapRelease Scoping and Namespaces
Helm releases are Namespace-scoped — a release name only needs to be unique within its Namespace. This enables clean multi-environment patterns:
# Same chart, three environments, three Namespaces
helm install frontend ./webapp -n dev
helm install frontend ./webapp -n staging
helm install frontend ./webapp -n prod -f values-prod.yamlBest practices:
- Include the environment in release names for cluster-wide uniqueness:
myapp-prod,myapp-dev - Use separate kubeconfig contexts or
--namespaceflags in CI/CD to prevent accidental prod deployments - Namespace-scoped RBAC can prevent dev engineers from installing into prod Namespaces
Helm in CI/CD Pipelines
The standard CI/CD pattern uses helm upgrade --install for idempotent deployment:
# Build stage
helm package ./myapp
# Test stage
helm lint ./myapp
helm template myapp ./myapp | kubeconform -strict
helm test myapp -n staging
# Deploy stage
helm upgrade --install myapp ./myapp \
--namespace prod \
--values values-prod.yaml \
--atomic \
--wait \
--timeout 10m \
--create-namespaceFlags explained:
| Flag | Purpose |
|---|---|
--install | Create the release if it does not exist |
--atomic | Rollback automatically if the upgrade fails |
--wait | Block until all resources are ready |
--timeout | Fail if deployment takes longer than N minutes |
--create-namespace | Create the target Namespace if missing |
Troubleshooting Releases
| Symptom | Diagnostic | Fix |
|---|---|---|
Release stuck in pending-install | Pod scheduling or image pull failure | kubectl get pods -n <ns>; check Events |
helm upgrade fails with “another operation in progress” | Previous upgrade was interrupted | helm rollback to last known good revision |
| Live state diverged from Helm history | Out-of-band kubectl edit | helm diff upgrade to see drift; re-apply chart |
Release exists but helm list is empty | Wrong Namespace or context | helm list -A; kubectl config current-context |
| Cannot rollback | Release history purged | Avoid --keep-history 0; set reasonable retention |
Related Pages
- Helm — Main concept page: architecture, commands, and ecosystem
- Helm Charts — Chart anatomy, authoring, and template patterns
- Kubernetes Namespaces — Release scoping and multi-tenancy
- Kubernetes RBAC — Controlling who can install/upgrade releases
- GitOps Security — Atomic deployments and rollback safety in pipelines
- Abhishek Veeramalla — Creator of the Helm Zero to Hero course
Tags: helm release-management kubernetes gitops rollback upgrade devops cicd