What is Helm?

Helm is a package manager for Kubernetes. Just like apt manages packages on Debian or brew on macOS, Helm manages Kubernetes applications. It bundles multiple K8s manifests into a single deployable unit called a Chart.

Without Helm
deployment.yaml
service.yaml
configmap.yaml
ingress.yaml
secret.yaml
hpa.yaml
... manage each one separately
vs
With Helm
helm install my-app ./chart

One command deploys everything

Three Core Concepts

Chart
A package of templated K8s manifests + metadata
Release
A specific instance of a chart deployed to a cluster
Repository
A place to store and share charts (like Docker Hub)

Chart Directory Structure

my-chart/
Chart.yaml required
Metadata: name, version, dependencies
values.yaml required
Default configuration values
charts/
Dependency charts (subcharts)
templates/
Go-templated K8s manifests
deployment.yaml
service.yaml
ingress.yaml
configmap.yaml
_helpers.tpl
Reusable template partials
NOTES.txt
Post-install usage notes
.helmignore
Files to exclude from packaging
Chart.yaml
apiVersion: v2
name: my-app
version: 1.2.0
appVersion: "3.1.0"
description: My app chart
dependencies:
  - name: postgresql
    version: "12.x"
    repository: "https://..."
values.yaml
replicaCount: 3
image:
  repository: myapp
  tag: "3.1.0"
service:
  type: ClusterIP
  port: 8080
ingress:
  enabled: true
  host: app.example.com

How Helm Renders & Deploys

Helm merges templates + values → renders plain YAML → applies to cluster

Templates
replicas: {{ .Values.replicaCount }}
image: {{ .Values.image.repo }}
+
Values
replicaCount: 3
image:
  repo: myapp:v2
Helm Template Engine
Go text/template + Sprig functions
Rendered Kubernetes YAML
apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 3          # resolved!
  containers:
    - image: myapp:v2  # resolved!
Kubernetes Cluster
kubectl apply (under the hood)
Value Override Priority (lowest → highest)
1 values.yaml (defaults)
2 -f custom.yaml
3 --set key=val
4 --set-string key=val

Release Lifecycle

Helm tracks every change as a numbered revision, making rollbacks trivial.

Install helm install my-release ./chart
Deploy chart as a new release → Revision 1
Upgrade helm upgrade my-release ./chart
Apply changes → Revision N+1 (keeps history)
Rollback helm rollback my-release 1
Revert to any previous revision instantly
Uninstall helm uninstall my-release
Remove all resources of the release from cluster
Revision History Example
Rev 1
install
Rev 2
upgrade
Rev 3
upgrade
Rev 4
rollback→2
helm history my-release shows all revisions
Other Useful Commands
helm list — List all releases
helm status my-release — Show release info
helm template ./chart — Render locally (dry run)
helm lint ./chart — Validate chart
helm dependency update — Pull sub-charts
helm package ./chart — Create .tgz archive

Go Templating in Helm

Helm uses Go's text/template with Sprig functions for powerful manifest generation.

Value Injection
Template
replicas: {{ .Values.replicaCount }}
image: {{ .Values.image.repo }}
Rendered
replicas: 3
image: myapp:v2.1.0
Conditionals
Template
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
  ...
{{- end }}
Rendered
# ingress.enabled = true
apiVersion: networking.k8s.io/v1
kind: Ingress
  ...
Loops
Template
{{- range .Values.env }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}
Rendered
- name: DB_HOST
  value: "postgres.svc"
- name: LOG_LEVEL
  value: "info"
Named Templates (_helpers.tpl)
Template
{{/* _helpers.tpl */}}
{{- define "mychart.labels" -}}
app: {{ .Chart.Name }}
version: {{ .Chart.AppVersion }}
{{- end }}

{{/* usage in template */}}
labels:
  {{- include "mychart.labels" . | nindent 4 }}
Rendered
labels:
    app: my-app
    version: 3.1.0
Built-in Objects
.Values Values from values.yaml and overrides .Chart Chart.yaml metadata (Name, Version, etc.) .Release Release info (Name, Namespace, Revision) .Template Current template file info .Capabilities K8s cluster capabilities & API versions

Related Topics