Helm for FDEs: package a deployment as a chart and install it for many customers without touching the templates
If you have to install one product into five customers' Kubernetes clusters, each with its own configuration, you need a package that is versioned, keeps a history and can be rolled back with a single command.
In brief
- The chart is the unit you bring to a customer's cluster: manifests live in templates, default configuration in values.yaml, and customer-specific configuration in a separate values file.
- Every install, upgrade or rollback increments the revision by 1, so every change to a customer's cluster has a number you can return to.
- Run helm template to preview manifests, distribute through an OCI registry and sign the package so customers can verify what they receive.
Imagine that next week you have to install the same service into two customers’ Kubernetes clusters: a bank that needs three replicas and an internal hostname, and a logistics company that needs only one replica. If you hand over a folder of loose YAML and edit it by hand for each site, by the third customer you will no longer remember what you changed where.
Helm’s homepage describes the project as the package manager for Kubernetes. The two-customer scenario above is exactly the kind of job a package manager exists to do.
For an FDE, Helm’s value is that it replaces “edit the YAML for the customer” with a versioned package. The customer can read that package, you can reinstall it, and when something breaks you can go back to the previous version.
What is in a chart?
According to Helm’s documentation, a chart is a collection of files that describe a related set of Kubernetes resources. At a minimum, a chart has three parts: Chart.yaml, which describes the package; a templates/ directory, which holds manifests with placeholders for values; and values.yaml, which holds the default configuration.
Two details are worth getting right from the start. Charts for Helm 3 and later must declare apiVersion: v2 in Chart.yaml. If the product needs a database or an ingress controller as well, declare them in the dependencies field of the same file rather than asking the customer to install each one themselves.
To see how values flow into a manifest, look at an excerpt from a Deployment template:
# templates/deployment.yaml (trích)
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: app
image: "myrepo/app:{{ .Values.image.tag }}"
If values.yaml sets replicaCount: 1 and image.tag: "1.4.0", the rendered manifest will have replicas: 1 and the image myrepo/app:1.4.0. For the bank, its own values file only needs replicaCount: 3; the template stays the same, and only the number filled in changes.
Treat values.yaml as the place for defaults that are safe for every customer. Anything that differs between customers (replica count, image tag, hostname, disk size) should be a key in this file. That way the tenth customer does not force you to edit a template.
Which value wins when three places set the same parameter?
At install time, you pass customer-specific configuration through one or more files with the -f flag, or as individual values with --set. Helm’s documentation is explicit: when both are used, --set values are merged into --values with higher precedence.
Work it through with the bank. values.yaml sets replicaCount: 1, the file values-nganhang.yaml (the bank’s values) sets replicaCount: 3, and during an incident someone adds --set replicaCount=5. The cluster will run 5 replicas, and the number 5 is not in any file you keep in Git.
So keep --set for quick experiments. A customer’s configuration belongs in a version-controlled values file, so that the next install produces exactly the same result as the last.
Before touching a customer’s cluster, run helm template. It renders the templates on your own machine and prints the manifests, so you can read exactly what Helm is about to create:
helm template ./my-chart -f values-nganhang.yaml
helm install my-app ./my-chart -f values-nganhang.yaml
When a customer has a platform team that wants to review changes, sending them the rendered manifests is more likely to win approval than sending a folder of templates.
Releases and revisions: why Helm is worth learning
Every time you install a chart, Helm creates a release. helm upgrade operates on an existing release, and helm rollback [RELEASE] [REVISION] returns it to an earlier revision. According to the documentation, each install, upgrade or rollback increments the revision number by 1.
Count through a week at the bank: the first install is revision 1, bumping the image tag is revision 2, changing the hostname is revision 3. The third version is broken, so you roll back to revision 2. The result is revision 4 with the contents of revision 2; the revision number does not go back to 2.
Because the number only goes up, the broken version stays in the history as number 3, just before the restored version numbered 4. When the customer asks “what did you change yesterday?”, you have a specific revision number to point to.
How do you deliver a chart so the customer can trust it?
Helm recommends using OCI-compliant container registries to store and share charts. If the customer already runs a registry for images, the chart can travel the same route without any extra infrastructure.
You can also sign the chart when packaging it so the customer can verify it on receipt. Helm’s documentation is blunt: if verification fails, there is reason to distrust the package. If the customer has a security team, prepare instructions in advance so they can verify the signature themselves before installing.
What Helm will not do for you
Helm installs exactly what the chart describes. If the template is wrong, or the customer’s values are wrong, Helm will install that mistake consistently. helm template helps you see errors, but you are still the one reading the output.
Charts declared in dependencies are also other people’s code running in the customer’s cluster. You need to know what resources they create before you put them in your package.
What about versions? Helm is a graduated CNCF project: it entered incubation in 2018 and reached Graduated status on 1 May 2020. In November 2025, Helm 4.0.0 was released at KubeCon, the first major version in six years.
apiVersion: v2 charts require at least Helm 3, and Helm 4 is now available. Ask the customer’s platform team which version they run in the very first technical meeting, not on installation day.
In what order should you learn it?
Start with chart structure and values.yaml, then the precedence between -f and --set, then the install, upgrade and rollback cycle on a test cluster. Packaging, signing and pushing to an OCI registry come last, but do not skip them.
If an FDE job description mentions Kubernetes, expect questions about Helm. On your CV, do not just write “knows Helm”. Say that you packaged a service as a chart, installed it across multiple environments with separate values files and have rolled back in production: describe the whole chain of work rather than just naming the tool.
A good chart makes the install for the fifth customer as boring as the install for the second.