# What is Helm in Kubernetes?

At its core, Helm gives you a way to template your YAML files (Deployments, Services, Ingress, etc.) and package them into something called a Chart—so you can deploy, upgrade, and rollback your apps cleanly and predictably.

Helm is often described as **“the package manager for Kubernetes.”** But if you’ve used tools like `apt`, `yum`, or `brew`, that analogy doesn’t quite tell the full story.

Yes, Helm helps you install apps in your cluster—but more importantly, it helps you manage the complexity of deploying Kubernetes resources in a consistent, reusable, and configurable way.

## Why Helm Exists (and Why You’ll Care Eventually)

You can absolutely write raw YAML and `kubectl apply -f` your way through life. And for small, static apps, that might be enough.

But once your workloads grow, or you have to:

- Deploy the same app across multiple environments (dev, staging, prod)
- Pass in different values (DB endpoints, feature flags, resource limits)
- Handle versioning and rollbacks
- Share templates across teams
- Install common off-the-shelf software (Prometheus, NGINX, ArgoCD, etc.)

…you’ll quickly realize that managing raw manifests manually is painful and error-prone.

Helm solves this by turning your Kubernetes resources into a **parameterized, versioned package**—complete with defaults, overrides, dependency management, and upgrade logic.

## The Core Concepts (Without the Buzzwords)

Helm introduces a few key ideas you’ll need to know:

### 1. **Chart**

A **Chart** is a package of Kubernetes manifests, parameterized with templates. It usually includes:

- `templates/` – folder with your YAML templates (e.g., Deployment, Service)
- `Chart.yaml` – metadata about the chart (name, version, etc.)
- `values.yaml` – default configuration values
- Optional: `charts/` (for dependencies) and `README.md`

You can think of it as a folder that describes **how to deploy something**, and it’s easy to version, lint, and share.

### 2. **Values**

Helm templates use Go templating syntax to insert dynamic content—powered by a `values.yaml` file.

Example values file:

```none
replicaCount: 3
image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
```

Inside your templates, you reference these values like this:

```none
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-nginx
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: nginx
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
```

You can override any of these values at install time:

```none
helm install my-nginx ./nginx-chart --values custom-values.yaml
```

Or set a quick value inline:

```none
helm install my-nginx ./nginx-chart --set replicaCount=5
```

### 3. **Release**

A **Release** is an instance of a chart deployed to a Kubernetes cluster. You can install the same chart multiple times with different configurations.

Example:

```none
helm install staging ./myapp-chart --namespace staging
helm install prod ./myapp-chart --namespace production
```

Each of those is a different release—even if they came from the same chart.

## Installing Helm and Using It

First, [install](https://helm.sh/) Helm. Then add a chart repo—like the official one from Bitnami or [Prometheus](/content/finops-glossary/prometheus/index.html):

```none
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
```

Now install something:

```none
helm install my-redis bitnami/redis
```

Boom—you’ve just deployed Redis to your cluster with sane defaults, persistent storage, and metrics enabled.

Want to customize it?

```none
helm show values bitnami/redis > redis-values.yaml
```

Then tweak the config and install:

```none
helm install my-redis bitnami/redis -f redis-values.yaml
```

## Upgrades, Rollbacks, and History

Helm tracks the state of each release. You can upgrade it when something changes:

```none
helm upgrade my-redis bitnami/redis -f redis-values.yaml
```

Or rollback if something breaks:

```none
helm rollback my-redis 1
```

You can see the release history:

```none
helm history my-redis
```

This is where Helm really shines: upgrades and rollbacks feel like first-class operations, not a pile of `kubectl apply` diffs you hope won’t break anything.

## How It Fits Into GitOps and CI/CD

Helm is a great building block for GitOps pipelines. You can store your Helm charts in Git, render them with tools like `helm template`, or use them directly with ArgoCD, Flux, or Jenkins.

In GitOps, you often don’t run `helm install` manually. Instead, you define your values in Git, and let your automation system deploy them.

That said, Helm works just as well for day-to-day ops:

- Quickly spinning up dev environments
- Testing app config changes
- Deploying standard services like metrics, logging, or cert managers

## When Not to Use Helm

Helm is powerful, but it’s not perfect. Here are a few caveats:

- The templating language (Go templates) can be clunky, especially for conditionals or nested logic
- Chart sprawl: you can end up with 30 different charts for small variations of the same app
- Debugging template rendering issues is a pain at first
- Charts from the ecosystem may have too many knobs or too much abstraction

If you’re doing very simple deployments or prefer full control over rendered manifests, tools like Kustomize or even plain YAML + `kubectl` might be enough.

## Summary

If you’re managing more than one environment, deploying anything third-party, or want to avoid repeating the same YAML 10 different ways—learn Helm.

It’s not a silver bullet, but it’s the most battle-tested tool we have right now for packaging, parameterizing, and managing Kubernetes apps.

Once you get past the initial learning curve, Helm makes life a whole lot easier—and far more consistent.
