Helm and Helm Chart
A package manager for Kubernetes that bundles all required Kubernetes manifests into a reusable unit called a chart. Helm templates variables at deploy time, enabling the same chart to deploy consistently across dev, staging, and production environments with different configurations.
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.
RememberHelm is to Kubernetes what
npmis 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
my-chart/├── Chart.yaml # chart name, version, description├── values.yaml # default config values└── templates/ ├── deployment.yaml # pod spec template ├── service.yaml # networking template ├── ingress.yaml # external access template └── serviceaccount.yamlChart.yaml
apiVersion: v2name: devops-networkdescription: Helm chart for DevOps Network Next.js apptype: applicationversion: 0.1.2appVersion: "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:
containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - containerPort: {{ .Values.service.port }} {{- if .Values.extraEnvs }} env: {{- toYaml .Values.extraEnvs | nindent 12 }} {{- end }} {{- if .Values.extraVolumeMounts }} volumeMounts: {{- toYaml .Values.extraVolumeMounts | nindent 12 }} {{- end }}{{- if .Values.extraVolumes }}volumes: {{- toYaml .Values.extraVolumes | nindent 8 }}{{- end }}TipAlways add
extraVolumesandextraVolumeMountssupport 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
replicaCount: 1 image: repository: 905418385260.dkr.ecr.ap-south-1.amazonaws.com/my-app tag: latest pullPolicy: IfNotPresent service: type: ClusterIP port: 3000 resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 256Mi extraEnvs: []extraVolumes: []extraVolumeMounts: []Environment override — dev.values.yaml
Only include keys you want to override. Everything else falls back to values.yaml:
ingress: enabled: true className: nginx hosts: - host: app.devopsnetwork.in paths: - path: / pathType: ImplementationSpecific serviceAccount: create: true name: devops-network-sa annotations: eks.amazonaws.com/role-arn: arn:aws:iam::905418385260:role/my-irsa-role extraEnvs: - name: NODE_ENV value: "production" - name: DATABASE_URL valueFrom: secretKeyRef: name: aws-secrets-manager-secret key: database-urlCommon MistakePutting secrets as plain text in
values.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
# Install a new releasehelm install devops-network ./chart -f dev.values.yaml -n devops-network # Upgrade an existing releasehelm upgrade devops-network ./chart -f dev.values.yaml -n devops-network # Install or upgrade (useful in CI pipelines)helm upgrade --install devops-network ./chart -f dev.values.yaml -n devops-network # Atomic upgrade — auto rollback on failurehelm upgrade --atomic devops-network ./chart -f prod.values.yaml -n production # View all releaseshelm list -n devops-network # View revision historyhelm history devops-network -n devops-network # Roll back to a specific revisionhelm rollback devops-network 2 -n devops-network # Remove a releasehelm uninstall devops-network -n devops-networkRevision history example
REVISION STATUS CHART DESCRIPTION1 deployed devops-network-0.1.0 Install complete2 deployed devops-network-0.1.1 Upgrade complete3 failed devops-network-0.1.2 Upgrade failedSecurityRollback 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.
TipAlways use
--atomicin 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
releases: - name: devops-network chart: oci://905418385260.dkr.ecr.eu-north-1.amazonaws.com/devops-network-helm/devops-network-testing version: {{ .StateValues.CHART_VERSION | quote }} namespace: devops-network-testing installed: true values: - values.yaml - "{{ .Environment.Name }}.values.yaml" set: - name: image.tag value: {{ .StateValues.BUILD_ID | quote }}Deploy commands
# Deploy dev environmenthelmfile -e dev apply # Deploy prod environmenthelmfile -e prod apply # Pass dynamic values at runtime (e.g. from CI pipeline)helmfile -e dev \ --state-values-set CHART_VERSION="0.1.2" \ --state-values-set BUILD_ID="1.0.5" \ apply # Preview diff before applying (uses helm-diff plugin)helmfile -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 templatingRememberHelmfile only upgrades releases that have actual changes — it runs
helm 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
# Authenticateaws ecr get-login-password --region ap-south-1 \ | helm registry login 905418385260.dkr.ecr.ap-south-1.amazonaws.com \ --username AWS --password-stdin # Package and pushhelm package ./devops-network-charthelm push devops-network-chart-0.1.2.tgz \ oci://905418385260.dkr.ecr.ap-south-1.amazonaws.com/devops-network-helmReference OCI chart in helmfile.yaml
chart: oci://905418385260.dkr.ecr.ap-south-1.amazonaws.com/devops-network-helm/devops-network-chartversion: "0.1.2"Common MistakeUsing a flat ECR repo name like
devops-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 |
Frequently Asked Questions
What's actually inside a Helm chart, and how does templating work at deploy time?
A chart is a directory with a Chart.yaml (metadata), a templates/ folder of Kubernetes manifests written with Go template syntax, and a values.yaml supplying default variables. At install time, Helm's templating engine substitutes values into the templates and renders final YAML, which it then applies via the Kubernetes API — similar to how Jinja renders a config file, but purpose-built for Kubernetes object structure.
When should you use a Helm chart versus plain Kustomize overlays?
Helm suits packaging reusable, distributable applications — especially third-party software you install as-is with a few overridden values (databases, ingress controllers, monitoring stacks). Kustomize suits patching your own manifests across environments without a templating layer, since it works with plain YAML and overlay patches rather than a templating language. Many teams use both: Helm for vendored charts, Kustomize for their own app overlays.