What Helm Charts Actually Are
A Helm chart is a directory (or packaged .tgz archive) containing a Chart.yaml metadata file, a values.yaml file of default configuration, and a templates/ directory of Kubernetes manifest files written with Go template syntax. Instead of hand-writing a Deployment, Service, and ConfigMap for every environment, you parameterize them once with {{ .Values.replicaCount }}-style placeholders and let Helm render the final YAML at install time. Helm tracks every install or upgrade as a numbered 'release', storing the rendered manifest and values as a Secret in the cluster so it can diff, upgrade, or roll back later.
Cricket analogy: Think of Chart.yaml and values.yaml like a franchise's playing-XI template for the IPL: the template defines batting order and roles, but you swap in Kohli or Gill for the opener slot per match without rewriting the whole strategy sheet.
Templating, Values, and Releases
Helm's templating engine supports conditionals, loops, named templates (_helpers.tpl), and subchart composition, so a single umbrella chart can pull in dependent charts like a Postgres or Redis chart listed under 'dependencies' in Chart.yaml. Values can be layered: chart defaults in values.yaml are overridden by a values-prod.yaml file passed with -f, and both are overridden by --set flags on the command line, giving a clear precedence order for CI/CD pipelines. Every helm upgrade creates a new release revision, and helm rollback <release> <revision> reverts the cluster to a prior rendered state by reapplying the stored manifest, not by re-running the old template against new values.
Cricket analogy: It's like DRS review layers in cricket: the on-field umpire's call is the base default, the third umpire's ball-tracking overrides it, and the final decision (like a --set flag) takes ultimate precedence.
Helm in CI/CD Practice
# Chart.yaml
apiVersion: v2
name: checkout-service
version: 1.4.0
appVersion: "2.3.1"
dependencies:
- name: postgresql
version: "13.2.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
---
# values.yaml (excerpt)
replicaCount: 3
image:
repository: registry.example.com/checkout-service
tag: "2.3.1"
resources:
requests: { cpu: 250m, memory: 256Mi }
limits: { cpu: 500m, memory: 512Mi }
---
# templates/deployment.yaml (excerpt)
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}In production pipelines, teams typically run helm template locally or in CI to render manifests for a diff review before applying, then use helm upgrade --install --atomic --wait so a failed rollout automatically rolls back rather than leaving the cluster half-upgraded. Combining this with helm lint (which validates chart structure) and a schema.json for values validation catches malformed configuration before it ever reaches a cluster, which matters most for stateful charts like databases where a bad rollout can cause data loss, not just downtime.
Cricket analogy: It's like a team management reviewing the batting order projection (helm template) before submitting the toss sheet, so no illegal player combination reaches the umpires — an --atomic upgrade is like a match being abandoned and replayed rather than leaving the scorecard half-finished.
helm upgrade --install without --atomic can leave a cluster in a partially-upgraded state if a rollout fails midway — always pair it with --atomic --wait --timeout in automated pipelines, and never run helm upgrade against production without first reviewing helm diff or helm template output.
- A Helm chart bundles Chart.yaml, values.yaml, and Go-templated manifests into one installable, versioned unit.
- Values precedence flows from chart defaults to -f override files to --set command-line flags, last one wins.
- Every helm upgrade creates a new release revision stored as a cluster Secret, enabling helm rollback.
- Subcharts declared under dependencies in Chart.yaml let you compose complex apps from reusable building blocks.
- helm template and helm lint let you catch rendering and structural errors before touching a live cluster.
- --atomic --wait ensures a failed upgrade automatically rolls back instead of leaving a half-applied state.
- Helm manages releases, not just manifests — rollback restores the previously rendered YAML, not a re-render of old values.
Practice what you learned
1. Which file in a Helm chart defines the default configurable values referenced by templates?
2. What does the --atomic flag do during a helm upgrade?
3. How does Helm typically store the state of a release in the cluster?
4. What is the correct override precedence for Helm values?
5. What command renders a chart's manifests locally without applying them to a cluster?
Was this page helpful?
You May Also Like
Kubernetes RBAC
Role-Based Access Control governs who can do what to which Kubernetes resources, using Roles, ClusterRoles, and Bindings to enforce least privilege.
Kubernetes Troubleshooting
A systematic approach to diagnosing failing pods, networking issues, and cluster-level problems using kubectl, events, and logs as your primary evidence.
Observability in Kubernetes
Observability in Kubernetes combines metrics, logs, and traces to answer not just whether something is broken, but why, across ephemeral pods and dynamic scheduling.