The templates/ Folder
Files in templates/ are rendered as Go templates and become the Kubernetes manifests Helm applies.
Syntax
helm template <chart>The templates/ directory is the heart of a chart. Every file here is run through Helm's template engine and the output is sent to Kubernetes.
What goes here
- One file per resource is the convention:
deployment.yaml,service.yaml,ingress.yaml. _helpers.tpl— files starting with an underscore are not rendered into manifests; they hold reusable snippets.NOTES.txt— rendered and printed after install, but not applied to the cluster.
Rendering
Use helm template to render the whole folder locally and see the exact YAML that would be applied — invaluable for debugging.
Example
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-svc
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
selector:
app: {{ .Release.Name }}When to use it
- A chart author writes a deployment.yaml in templates/ using Go template syntax so the chart can produce different manifests for each environment from the same source.
- A developer adds a NOTES.txt to templates/ so helm install prints connection instructions after the release is created, improving operator experience.
- A platform team organises the templates/ directory into sub-folders by resource type so a large chart with 15 manifests remains navigable.
More examples
Basic Deployment template
Shows a realistic Deployment template using named helpers for the name and labels, and .Values for replica count.
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}NOTES.txt post-install message
NOTES.txt is also rendered as a template; its output is printed to the terminal after helm install or helm upgrade.
# templates/NOTES.txt
Application {{ .Release.Name }} is now running.
Get the application URL:
kubectl port-forward svc/{{ include "myapp.fullname" . }} 8080:{{ .Values.service.port }}Render templates locally
Renders all files in templates/ to stdout without contacting Kubernetes, letting you inspect the final YAML before applying.
helm template my-release ./myapp \
-f values-prod.yaml \
--debug
Discussion