Helm — Comprehensive Production Guide
Helm eliminates the chaos of managing 5-6 separate Kubernetes YAML files per service. Instead of manually editing Deployment, Service, Ingress, and ServiceAccount manifests for every deploy, Helm packages them into one versioned chart and applies them with a single command.
📌 Remember: Helm is to Kubernetes what npm is to Node.js — a package manager that handles versioning, upgrades, and rollbacks.Helm Chart
A chart is the core Helm unit — a folder containing all Kubernetes manifest templates and configuration defaults for one application.
Chart structure
1my-chart/2├── Chart.yaml # chart name, version, description3├── values.yaml # default config values4└── templates/5 ├── deployment.yaml # pod spec template6 ├── service.yaml # networking template7 ├── ingress.yaml # external access template8 └── serviceaccount.yamlChart.yaml
1apiVersion: v22name: devops-network3description: Helm chart for DevOps Network Next.js app4type: application5version: 0.1.26appVersion: "1.0.0"📌 Remember:versionis the chart version — bump it every time you change templates.appVersionis the version of the application itself.
Templates use Go template variables that Helm fills at deploy time:
1containers:2 - name: {{ .Chart.Name }}3 image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"4 ports:5 - containerPort: {{ .Values.service.port }}6 {{- if .Values.extraEnvs }}7 env:8 {{- toYaml .Values.extraEnvs | nindent 12 }}9 {{- end }}10 {{- if .Values.extraVolumeMounts }}11 volumeMounts:12 {{- toYaml .Values.extraVolumeMounts | nindent 12 }}13 {{- end }}14{{- if .Values.extraVolumes }}15volumes:16 {{- toYaml .Values.extraVolumes | nindent 8 }}17{{- end }}💡 Tip: Always addextraVolumesandextraVolumeMountssupport to your deployment template from the start. Adding them later requires a chart version bump and redeployment.
values.yaml
The default configuration file for a chart. All tunable parameters live here — image tag, replica count, resource limits, env vars. Environment-specific files like dev.values.yaml override these defaults at deploy time.
Base values.yaml
1replicaCount: 12 3image:4 repository: 905418385260.dkr.ecr.ap-south-1.amazonaws.com/my-app5 tag: latest6 pullPolicy: IfNotPresent7 8service:9 type: ClusterIP10 port: 300011 12resources:13 limits:14 cpu: 500m15 memory: 512Mi16 requests:17 cpu: 100m18 memory: 256Mi19 20extraEnvs: []21extraVolumes: []22extraVolumeMounts: []Environment override — dev.values.yaml
Only include keys you want to override. Everything else falls back to values.yaml:
1ingress:2 enabled: true3 className: nginx4 hosts:5 - host: app.devopsnetwork.in6 paths:7 - path: /8 pathType: ImplementationSpecific9 10serviceAccount:11 create: true12 name: devops-network-sa13 annotations:14 eks.amazonaws.com/role-arn: arn:aws:iam::905418385260:role/my-irsa-role15 16extraEnvs:17 - name: NODE_ENV18 value: "production"19 - name: DATABASE_URL20 valueFrom:21 secretKeyRef:22 name: aws-secrets-manager-secret23 key: database-url🔴 Common Mistake: Putting secrets as plain text invalues.yamlcommitted to your repo. Always usesecretKeyRefpointing to a Kubernetes Secret, and store actual values in AWS Secrets Manager or Vault.
Helm Release
A running instance of a Helm chart deployed to a Kubernetes cluster. The same chart can be installed multiple times as different releases — each with its own name, namespace, and values. Helm tracks each release's revision history, enabling instant upgrades and rollbacks.
Core release commands
1# Install a new release2helm install devops-network ./chart -f dev.values.yaml -n devops-network3 4# Upgrade an existing release5helm upgrade devops-network ./chart -f dev.values.yaml -n devops-network6 7# Install or upgrade (useful in CI pipelines)8helm upgrade --install devops-network ./chart -f dev.values.yaml -n devops-network9 10# Atomic upgrade — auto rollback on failure11helm upgrade --atomic devops-network ./chart -f prod.values.yaml -n production12 13# View all releases14helm list -n devops-network15 16# View revision history17helm history devops-network -n devops-network18 19# Roll back to a specific revision20helm rollback devops-network 2 -n devops-network21 22# Remove a release23helm uninstall devops-network -n devops-networkRevision history example
1REVISION STATUS CHART DESCRIPTION21 deployed devops-network-0.1.0 Install complete32 deployed devops-network-0.1.1 Upgrade complete43 failed devops-network-0.1.2 Upgrade failed⚠️ Security: Rollback restores Kubernetes resource config only — Deployment spec, env vars, image tag. It does NOT revert database migrations or external state. Always test rollback in staging before a production incident.
💡 Tip: Always use --atomic in production pipelines. If new pods fail health checks, Helm automatically rolls back to the previous revision without manual intervention.Helmfile
A declarative wrapper on top of Helm. Instead of running separate helm upgrade commands for each environment, Helmfile lets you define all releases, charts, and environment-specific values in one helmfile.yaml — deploying everything with a single helmfile apply command.
helmfile.yaml
1releases:2 - name: devops-network3 chart: oci://905418385260.dkr.ecr.eu-north-1.amazonaws.com/devops-network-helm/devops-network-testing4 version: {{ .StateValues.CHART_VERSION | quote }}5 namespace: devops-network-testing6 installed: true7 values:8 - values.yaml9 - "{{ .Environment.Name }}.values.yaml"10 set:11 - name: image.tag12 value: {{ .StateValues.BUILD_ID | quote }}Deploy commands
1# Deploy dev environment2helmfile -e dev apply3 4# Deploy prod environment5helmfile -e prod apply6 7# Pass dynamic values at runtime (e.g. from CI pipeline)8helmfile -e dev \9 --state-values-set CHART_VERSION="0.1.2" \10 --state-values-set BUILD_ID="1.0.5" \11 apply12 13# Preview diff before applying (uses helm-diff plugin)14helmfile -e dev diffHow value merging works
Helmfile layers values files in order — later files override earlier ones:
values.yaml ← base defaults (replicas, resources, image repo) +dev.values.yaml ← environment overrides (ingress host, secrets, env vars) =Final merged config ← sent to Helm for templating📌 Remember: Helmfile only upgrades releases that have actual changes — it runshelm diffinternally and skips unchanged releases. This makeshelmfile applysafe to run on every pipeline push.
OCI Chart Registry
Helm charts can be stored in any OCI-compatible container registry alongside Docker images. AWS ECR, GitHub Container Registry, and Docker Hub all support OCI chart storage — no separate chart server needed.
Push chart to ECR
1# Authenticate2aws ecr get-login-password --region ap-south-1 \3 | helm registry login 905418385260.dkr.ecr.ap-south-1.amazonaws.com \4 --username AWS --password-stdin5 6# Package and push7helm package ./devops-network-chart8helm push devops-network-chart-0.1.2.tgz \9 oci://905418385260.dkr.ecr.ap-south-1.amazonaws.com/devops-network-helmReference OCI chart in helmfile.yaml
1chart: oci://905418385260.dkr.ecr.ap-south-1.amazonaws.com/devops-network-helm/devops-network-chart2version: "0.1.2"🔴 Common Mistake: Using a flat ECR repo name likedevops-network-helm. ECR OCI push requires the full nested path —devops-network-helm/devops-network-chartas the repository name. Creating the repo with just the parent name will cause a push failure.
Quick Reference
| Command | What it does |
|---|---|
helm install <name> <chart> |
Install a new release |
helm upgrade --install <name> <chart> |
Install or upgrade |
helm upgrade --atomic <name> <chart> |
Upgrade with auto rollback on failure |
helm rollback <name> <revision> |
Restore a previous revision |
helm history <name> |
View revision history |
helm list -n <namespace> |
List all releases in namespace |
helm template <name> <chart> |
Preview rendered YAML without deploying |
helm diff upgrade <name> <chart> |
Show diff before upgrading |
helmfile -e <env> apply |
Deploy all releases for an environment |
helmfile -e <env> diff |
Preview all changes before applying |