Writing Charts
Templates and values.
Using other people's charts is useful. But sooner or later, you will package your own app. A chart is simply your Y A M L files, with the changing parts replaced by variables. In this lesson, you will see the folder layout, the templates, and the values that fill them in.

- A chart is a folder
- Templates hold placeholders
- Values fill them in
The anatomy of a chart
A chart has a simple layout. Chart dot yaml is the identity card, with the name and the version. Values dot yaml holds the default settings. The templates folder holds your Kubernetes files, with placeholders. And optional folders hold sub charts, the dependencies. When you install, Helm combines the templates with the values, and sends the finished Y A M L to the cluster.
- Chart.yamlname and version
- values.yamldefault settings
- templates/Kubernetes files with placeholders
- charts/dependencies
A template
Here is a template. It looks like a normal deployment, but some values are written in double curly braces. The release name, becomes part of the object's name, so two releases never clash. The replica count is read from the values. And the image comes from two values, the repository, and the tag. So the same template can produce a small test setup, or a large production one, depending on the values.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-web
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"The values file
And here are the default values. A replica count of two, and the image, engine X, tag one point twenty seven. When you install, you can override any of them. Dash dash set changes one value, and dash f points to your own values file, for example, one file per environment. Keep the chart generic, and put the differences in the values.
replicaCount: 2
image:
repository: nginx
tag: "1.27"Create, lint, template, install
Helm can scaffold a chart for you. The create command makes a folder, with all the standard files. We look at its default values. Lint checks the chart for mistakes. Template renders the finished Y A M L on your screen, without touching the cluster, a great way to debug. And install sends it to the cluster. The release is listed, and its pods are running.
helm create mychart Creating mychart ls mychart Chart.yaml charts templates values.yaml grep -v '^ *#' mychart/values.yaml | grep -v '^$' | head -8 replicaCount: 1 image: repository: nginx pullPolicy: IfNotPresent tag: "" imagePullSecrets: [] nameOverride: "" fullnameOverride: "" helm lint mychart ==> Linting mychart [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, 0 chart(s) failed helm template demo mychart | head -12 --- # Source: mychart/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: name: demo-mychart labels: helm.sh/chart: mychart-0.1.0 app.kubernetes.io/name: mychart helm install demo ./mychart --set replicaCount=2 --wait NAME: demo LAST DEPLOYED: Fri Oct 30 23:42:00 2026 NAMESPACE: default STATUS: deployed REVISION: 1 NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=demo" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION demo default 1 2026-10-30 23:42:00.213695 +0300 +03 deployed mychart-0.1.0 1.16.0 kubectl get pods -l app.kubernetes.io/instance=demo NAME READY STATUS RESTARTS AGE demo-mychart-98bffbb88-bxgwv 1/1 Running 0 7s demo-mychart-98bffbb88-x2mp9 1/1 Running 0 7s
Summary
Wonderful. A chart is a folder, templates hold placeholders, and values fill them in. You can lint, template, and install your own charts. Next, a different approach to the same problem, without templates, Kustomize.
Key takeaways- Chart.yaml, values.yaml, templates/
- {{ .Values.x }} placeholders
- helm template previews safely