DEV Community

Cover image for Day 25 - Helm Chart
Rahul Joshi
Rahul Joshi

Posted on

Day 25 - Helm Chart

Kubernetes is powerful, but managing Kubernetes YAML files manually becomes difficult very quickly.

A simple application may need:

  • Deployment
  • Service
  • ConfigMap
  • Secret
  • Ingress
  • HPA
  • ServiceAccount
  • RBAC
  • NetworkPolicy

If you write everything manually, your project can easily become messy.

This is where Helm comes in.

Helm is often called:

The package manager for Kubernetes
Enter fullscreen mode Exit fullscreen mode

Just like:

apt installs packages on Ubuntu
yum installs packages on RHEL
npm installs packages for Node.js
Helm installs applications on Kubernetes
Enter fullscreen mode Exit fullscreen mode

πŸ”— Resources


What is Helm?

Helm is a Kubernetes package manager that helps you define, install, upgrade, and manage Kubernetes applications.

Instead of applying many YAML files one by one:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f configmap.yaml
kubectl apply -f ingress.yaml
Enter fullscreen mode Exit fullscreen mode

You can install everything using one Helm command:

helm install my-app ./my-chart
Enter fullscreen mode Exit fullscreen mode

Helm packages Kubernetes manifests into a reusable unit called a Helm Chart.


What is a Helm Chart?

A Helm Chart is a collection of files that describe a Kubernetes application.

A chart contains:

  • Kubernetes templates
  • Default configuration values
  • Metadata
  • Helper templates
  • Dependency definitions

Think of a Helm Chart as:

Reusable Kubernetes application package
Enter fullscreen mode Exit fullscreen mode

Example:

nginx-chart
 β”œβ”€β”€ Deployment
 β”œβ”€β”€ Service
 β”œβ”€β”€ ConfigMap
 β”œβ”€β”€ Ingress
 └── Values
Enter fullscreen mode Exit fullscreen mode

Why Do We Need Helm?

Without Helm, Kubernetes YAML becomes repetitive.

Example problem:

You have three environments:

dev
qa
prod
Enter fullscreen mode Exit fullscreen mode

Each environment needs the same application but different values.

Dev:

replicas: 1
image: app:dev
Enter fullscreen mode Exit fullscreen mode

Prod:

replicas: 5
image: app:v1.0.0
Enter fullscreen mode Exit fullscreen mode

Without Helm, you may create separate YAML files for every environment.

With Helm, you create one reusable chart and change only values.


Helm Solves These Problems

1. Reusability

One chart can be reused across environments.

Same Chart
   ↓
dev-values.yaml
qa-values.yaml
prod-values.yaml
Enter fullscreen mode Exit fullscreen mode

2. Easy Configuration

You can customize deployments using values.yaml.


3. Version Control

Helm charts can be versioned.

Example:

my-app-chart-1.0.0
my-app-chart-1.1.0
my-app-chart-2.0.0
Enter fullscreen mode Exit fullscreen mode

4. Easy Upgrade and Rollback

Upgrade:

helm upgrade my-app ./my-chart
Enter fullscreen mode Exit fullscreen mode

Rollback:

helm rollback my-app 1
Enter fullscreen mode Exit fullscreen mode

5. Better Release Management

Helm tracks every release.

helm list
Enter fullscreen mode Exit fullscreen mode

helm flow


Helm Architecture

When you run:

helm install
Enter fullscreen mode Exit fullscreen mode

Helm renders templates into Kubernetes YAML and sends them to the Kubernetes API server.


Helm Chart File Structure

When you create a chart:

helm create my-app
Enter fullscreen mode Exit fullscreen mode

Helm creates this structure:

my-app/
β”œβ”€β”€ Chart.yaml
β”œβ”€β”€ values.yaml
β”œβ”€β”€ charts/
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ deployment.yaml
β”‚   β”œβ”€β”€ service.yaml
β”‚   β”œβ”€β”€ ingress.yaml
β”‚   β”œβ”€β”€ serviceaccount.yaml
β”‚   β”œβ”€β”€ hpa.yaml
β”‚   β”œβ”€β”€ _helpers.tpl
β”‚   └── NOTES.txt
└── .helmignore
Enter fullscreen mode Exit fullscreen mode

Now let’s understand every important file.


Chart.yaml

Chart.yaml contains metadata about the chart.

Example:

apiVersion: v2
name: my-app
description: A Helm chart for deploying my application
type: application
version: 1.0.0
appVersion: "1.0.0"
Enter fullscreen mode Exit fullscreen mode

Explanation:

apiVersion: Helm chart API version
name: Chart name
description: Short chart description
type: application or library
version: Chart version
appVersion: Application version
Enter fullscreen mode Exit fullscreen mode

Important difference:

version     = Helm chart version
appVersion  = Application version
Enter fullscreen mode Exit fullscreen mode

values.yaml

values.yaml stores default values for the chart.

Example:

replicaCount: 2

image:
  repository: nginx
  tag: "1.25"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi
Enter fullscreen mode Exit fullscreen mode

This file makes your chart configurable.

Instead of hardcoding values inside Kubernetes YAML, Helm reads them from values.yaml.


templates/ Directory

The templates/ folder contains Kubernetes YAML templates.

These are not normal YAML files.

They contain template expressions like:

{{ .Values.replicaCount }}
Enter fullscreen mode Exit fullscreen mode

Helm replaces these values during rendering.


Deployment Template Example

apiVersion: apps/v1
kind: Deployment

metadata:
  name: {{ .Release.Name }}-app

spec:
  replicas: {{ .Values.replicaCount }}

  selector:
    matchLabels:
      app: {{ .Chart.Name }}

  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}

    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

If values.yaml contains:

replicaCount: 3

image:
  repository: nginx
  tag: "1.25"
Enter fullscreen mode Exit fullscreen mode

Helm renders:

replicas: 3
image: nginx:1.25
Enter fullscreen mode Exit fullscreen mode

Service Template Example

apiVersion: v1
kind: Service

metadata:
  name: {{ .Release.Name }}-service

spec:
  type: {{ .Values.service.type }}

  ports:
    - port: {{ .Values.service.port }}
      targetPort: 80

  selector:
    app: {{ .Chart.Name }}
Enter fullscreen mode Exit fullscreen mode

This means the same chart can create different service types:

service:
  type: ClusterIP
Enter fullscreen mode Exit fullscreen mode

or:

service:
  type: LoadBalancer
Enter fullscreen mode Exit fullscreen mode

What is Helm Templating?

Helm templating allows you to dynamically generate Kubernetes YAML.

Example:

replicas: {{ .Values.replicaCount }}
Enter fullscreen mode Exit fullscreen mode

This means:

Take replicaCount value from values.yaml
Enter fullscreen mode Exit fullscreen mode

Helm templates are powered by Go templating.


Common Helm Template Objects

.Values

Reads values from values.yaml.

{{ .Values.image.repository }}
Enter fullscreen mode Exit fullscreen mode

.Release

Provides release information.

{{ .Release.Name }}
Enter fullscreen mode Exit fullscreen mode

Example:

helm install dev-app ./my-chart
Enter fullscreen mode Exit fullscreen mode

Then:

{{ .Release.Name }}
Enter fullscreen mode Exit fullscreen mode

becomes:

dev-app
Enter fullscreen mode Exit fullscreen mode

.Chart

Provides chart metadata.

{{ .Chart.Name }}
Enter fullscreen mode Exit fullscreen mode

.Namespace

Returns release namespace.

{{ .Release.Namespace }}
Enter fullscreen mode Exit fullscreen mode

_helpers.tpl

_helpers.tpl stores reusable template snippets.

Example:

{{- define "my-app.fullname" -}}
{{ .Release.Name }}-{{ .Chart.Name }}
{{- end }}
Enter fullscreen mode Exit fullscreen mode

Use it like:

name: {{ include "my-app.fullname" . }}
Enter fullscreen mode Exit fullscreen mode

This keeps templates clean and avoids duplication.


NOTES.txt

NOTES.txt displays information after chart installation.

Example:

Application installed successfully.

Access your app using:

kubectl port-forward svc/{{ .Release.Name }}-service 8080:80
Enter fullscreen mode Exit fullscreen mode

After install, Helm prints this message.


.helmignore

.helmignore works like .gitignore.

It tells Helm which files to ignore while packaging the chart.

Example:

.git/
README.md
*.log
Enter fullscreen mode Exit fullscreen mode

Helm Install Command

Install a chart:

helm install my-app ./my-app
Enter fullscreen mode Exit fullscreen mode

Check release:

helm list
Enter fullscreen mode Exit fullscreen mode

Check Kubernetes resources:

kubectl get all
Enter fullscreen mode Exit fullscreen mode

Helm Upgrade Command

If you update image tag or replicas:

helm upgrade my-app ./my-app
Enter fullscreen mode Exit fullscreen mode

Example:

helm upgrade my-app ./my-app \
  --set image.tag=1.26
Enter fullscreen mode Exit fullscreen mode

Helm Rollback Command

Check release history:

helm history my-app
Enter fullscreen mode Exit fullscreen mode

Rollback:

helm rollback my-app 1
Enter fullscreen mode Exit fullscreen mode

This is one of Helm’s most useful features.


Helm Uninstall Command

Remove release:

helm uninstall my-app
Enter fullscreen mode Exit fullscreen mode

This deletes all Kubernetes resources created by that Helm release.


Using Multiple Values Files

You can create different values files:

values-dev.yaml
values-qa.yaml
values-prod.yaml
Enter fullscreen mode Exit fullscreen mode

Example dev:

replicaCount: 1
image:
  tag: dev
service:
  type: ClusterIP
Enter fullscreen mode Exit fullscreen mode

Example prod:

replicaCount: 5
image:
  tag: v1.0.0
service:
  type: LoadBalancer
Enter fullscreen mode Exit fullscreen mode

Install dev:

helm install my-app-dev ./my-app -f values-dev.yaml
Enter fullscreen mode Exit fullscreen mode

Install prod:

helm install my-app-prod ./my-app -f values-prod.yaml
Enter fullscreen mode Exit fullscreen mode

Same chart, different environments.


Helm Dry Run

Before installing, test the chart:

helm install my-app ./my-app --dry-run --debug
Enter fullscreen mode Exit fullscreen mode

This shows rendered YAML without applying it.

Useful for debugging.


Helm Template Command

Render YAML locally:

helm template my-app ./my-app
Enter fullscreen mode Exit fullscreen mode

This is useful when you want to inspect final Kubernetes manifests.


Helm Lint

Check chart issues:

helm lint ./my-app
Enter fullscreen mode Exit fullscreen mode

It validates chart structure and common problems.


helm Flow Proper

Popular chart repositories:

  • ArtifactHub
  • JFrog Artifactory
  • Sonatype Nexus
  • GitHub Pages
  • OCI Registry

Packaging a Helm Chart

Package chart:

helm package my-app
Enter fullscreen mode Exit fullscreen mode

Output:

my-app-1.0.0.tgz
Enter fullscreen mode Exit fullscreen mode

This package can be uploaded to a chart repository.


Installing Public Helm Charts

Add repo:

helm repo add bitnami https://charts.bitnami.com/bitnami
Enter fullscreen mode Exit fullscreen mode

Update repo:

helm repo update
Enter fullscreen mode Exit fullscreen mode

Install chart:

helm install my-nginx bitnami/nginx
Enter fullscreen mode Exit fullscreen mode

Helm for Kubernetes Deployments

Kubernetes deployment without Helm:

deployment.yaml
service.yaml
ingress.yaml
configmap.yaml
secret.yaml
Enter fullscreen mode Exit fullscreen mode

Kubernetes deployment with Helm:

helm install my-app ./chart
Enter fullscreen mode Exit fullscreen mode

Helm makes Kubernetes deployment cleaner, reusable, and easier to manage.


Complete Example: NGINX Helm Chart

Create chart:

helm create nginx-chart
Enter fullscreen mode Exit fullscreen mode

Update values.yaml:

replicaCount: 2

image:
  repository: nginx
  tag: "1.25"

service:
  type: ClusterIP
  port: 80
Enter fullscreen mode Exit fullscreen mode

Update templates/deployment.yaml:

apiVersion: apps/v1
kind: Deployment

metadata:
  name: {{ .Release.Name }}-nginx

spec:
  replicas: {{ .Values.replicaCount }}

  selector:
    matchLabels:
      app: nginx

  template:
    metadata:
      labels:
        app: nginx

    spec:
      containers:
        - name: nginx
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Update templates/service.yaml:

apiVersion: v1
kind: Service

metadata:
  name: {{ .Release.Name }}-service

spec:
  type: {{ .Values.service.type }}

  selector:
    app: nginx

  ports:
    - port: {{ .Values.service.port }}
      targetPort: 80
Enter fullscreen mode Exit fullscreen mode

Install:

helm install nginx-demo ./nginx-chart
Enter fullscreen mode Exit fullscreen mode

Verify:

kubectl get pods
kubectl get svc
Enter fullscreen mode Exit fullscreen mode

Reusable Deployments with Helm

Helm helps platform teams create reusable templates.

Example:

Frontend Team
Backend Team
Payment Team
Order Team
Enter fullscreen mode Exit fullscreen mode

All can use the same base chart.

Only values change:

image.repository
image.tag
replicaCount
resources
env
ingress.host
Enter fullscreen mode Exit fullscreen mode

This creates standardization across teams.


Helm in CI/CD Pipeline

Modern CI/CD pipeline:

Developer Commit
      ↓
Build Docker Image
      ↓
Push Image to Registry
      ↓
Update Helm values
      ↓
helm upgrade
      ↓
Kubernetes Deployment
Enter fullscreen mode Exit fullscreen mode

Example:

helm upgrade my-app ./chart \
  --set image.tag=$GITHUB_SHA
Enter fullscreen mode Exit fullscreen mode

Helm with GitOps

In modern Kubernetes, Helm is often used with GitOps tools.

Example:

Git Repository
      ↓
Helm Chart
      ↓
ArgoCD / Flux
      ↓
Kubernetes Cluster
Enter fullscreen mode Exit fullscreen mode

ArgoCD can deploy Helm charts directly.


Helm Best Practices

1. Keep Charts Reusable

Avoid hardcoding environment-specific values.

Bad:

replicas: 5
Enter fullscreen mode Exit fullscreen mode

Good:

replicas: {{ .Values.replicaCount }}
Enter fullscreen mode Exit fullscreen mode

2. Use values.yaml Properly

Keep all configurable values in values.yaml.


3. Use Separate Values Files

Use:

values-dev.yaml
values-prod.yaml
Enter fullscreen mode Exit fullscreen mode

4. Run helm lint

Always validate charts.

helm lint ./chart
Enter fullscreen mode Exit fullscreen mode

5. Use Versioning

Always version charts properly.

version: 1.0.0
appVersion: "1.0.0"
Enter fullscreen mode Exit fullscreen mode

6. Avoid Storing Secrets Directly

Do not store plain secrets in values files.

Use:

  • External Secrets Operator
  • Sealed Secrets
  • HashiCorp Vault
  • AWS Secrets Manager
  • Azure Key Vault

Common Helm Commands

helm create my-chart
helm install my-app ./my-chart
helm upgrade my-app ./my-chart
helm rollback my-app 1
helm uninstall my-app
helm list
helm history my-app
helm template my-app ./my-chart
helm lint ./my-chart
helm package my-chart
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Helm is one of the most important tools in the Kubernetes ecosystem.

It solves a very real problem:

Too many YAML files
Too much repetition
Too much manual configuration
Enter fullscreen mode Exit fullscreen mode

With Helm, you get:

  • Reusable deployments
  • Environment-based configuration
  • Template-based Kubernetes manifests
  • Easy upgrades
  • Easy rollbacks
  • Better release management

If Kubernetes is the platform for running containers, Helm is the tool that makes Kubernetes applications easier to package, reuse, and operate.

For DevOps Engineers, Cloud Engineers, SREs, and Platform Engineers, Helm is not optional anymore.

It is a must-have Kubernetes skill.

Top comments (0)