| name | helm-charts |
| description | Create, write, build, develop, debug, test, package, and deploy Helm charts with templates, values, helpers, dependencies, and tests. Use when authoring Kubernetes charts, writing values.yaml, creating _helpers.tpl, managing chart dependencies, or troubleshooting template errors. |
| license | MIT |
| metadata | {"version":"1.0.0","audience":"developers","workflow":"infrastructure"} |
Helm Charts Skill
What I Do
- Create Helm charts with proper structure (Chart.yaml, values.yaml, templates/)
- Write Go templates for Kubernetes manifests
- Design values.yaml with --set compatible patterns
- Build named templates in _helpers.tpl
- Manage chart dependencies and environment overrides
- Write chart tests and debug template errors
- Package charts for repository distribution
When to Use Me
Use this skill when you:
- Create, scaffold, or generate a new Helm chart
- Write, edit, or debug template files (.yaml, .tpl)
- Design or restructure values.yaml configuration
- Add or configure chart dependencies
- Create named templates (_helpers.tpl)
- Write or run helm tests
- Debug template rendering or YAML errors
Chart Structure
mychart/
Chart.yaml # Required: name, version, apiVersion
values.yaml # Default configuration
charts/ # Dependencies
templates/
_helpers.tpl # Named templates
deployment.yaml
service.yaml
NOTES.txt # Post-install message
tests/test-connection.yaml
Template Patterns
image: {{ .Values.image | default "nginx" }}
name: {{ required "name required" .Values.name }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
{{- end }}
{{- range .Values.ports }}
- port: {{ .port }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{ .Release.Name }}
{{ .Release.Namespace }}
{{ }}
Values Management
replicaCount: 3
replica-count: 3
serverPort: 8080
serverHost: example.com
image:
repository: nginx
tag: "1.21"
Environment overrides:
helm install myapp ./chart -f values.yaml -f values-prod.yaml
Named Templates (_helpers.tpl)
{{- define "myapp.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "myapp.labels" -}}
app.kubernetes.io/name: {{ include "myapp.fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "myapp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "myapp.fullname" . }}
{{- end }}
Usage (prefer include over template):
metadata:
labels:
{{- include "myapp.labels" . | nindent 4 }}
Dependencies
dependencies:
- name: postgresql
version: "11.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
helm repo add bitnami https://charts.bitnami.com/bitnami
helm dependency update ./mychart
Global values (shared with subcharts):
global:
imageRegistry: registry.example.com
Testing
helm lint ./mychart
helm template myrelease ./mychart
helm install test ./mychart --dry-run
helm test myrelease
Test pod template:
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "myapp.fullname" . }}-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: test
image: busybox
command: ['wget', '{{ include "myapp.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
Modern Helm Workflows
Upgrade with Install (CI Default)
helm upgrade --install myrelease ./mychart \
--namespace production \
--create-namespace \
--wait \
--timeout 5m
Values Schema Validation
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["replicaCount"],
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
}
}
}
Dry Run with Server Validation
helm template myrelease ./mychart | kubectl apply --dry-run=server -f -
Helm Diff Plugin (PR Previews)
helm plugin install https://github.com/databus23/helm-diff
helm diff upgrade myrelease ./mychart -f values-prod.yaml
Hooks
Hooks let a chart run Kubernetes resources at specific points in the release lifecycle (e.g., run a DB migration Job before the new app pods start). Annotate any resource with helm.sh/hook to make it a hook.
| Phase | Use Case |
|---|
pre-install, post-install | Bootstrap, schema migrations, seeding |
pre-upgrade, post-upgrade | DB migrations, cache warmup |
pre-delete, post-delete | Backup, cleanup |
test | Helm test pod (run with helm test) |
Important: Hooks are tracked in release metadata (helm status). Delete them with helm uninstall --keep-history=false or run them again with helm upgrade --reuse-values.
Example: pre-upgrade DB migration Job
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "myapp.fullname" . }}-migrate
labels:
{{- include "myapp.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["node", "./scripts/migrate.js"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ include "myapp.fullname" }}
Hook deletion policies:
before-hook-creation — delete previous hook when a new one is created (default for upgrades)
hook-succeeded — delete after successful run
hook-failed — delete after a failed run
For database migrations, before-hook-creation,hook-succeeded ensures the migration Job is re-runnable on every upgrade but cleaned up after success.
OCI Registry (Helm v3.8+)
Helm v3.8+ treats registries as first-class chart repositories via the OCI artifact spec. No helm repo add needed — helm push and helm pull speak OCI directly.
Push to OCI registry
helm registry login registry.example.com --username <user> --password <token>
helm package ./mychart
helm push mychart-0.1.0.tgz oci://registry.example.com/charts
Pull and install from OCI
helm pull oci://registry.example.com/charts/mychart --version 0.1.0
helm install myrelease oci://registry.example.com/charts/mychart --version 0.1.0
Common OCI registries: AWS ECR (<aws_account_id>.dkr.ecr.<region>.amazonaws.com), GCP Artifact Registry, Azure Container Registry, GitHub Container Registry (ghcr.io/<org>/charts), Harbor.
For CI workflows, authenticate with the registry's native token (e.g., aws ecr get-login-password for ECR) and helm push from a build job. See the github-actions skill for OIDC patterns that pair well with OCI chart publishing.
Context7 Integration
Use Context7 MCP server for up-to-date Helm documentation:
- Template function reference
- Best practices for current Helm version
- New features and deprecations
Common Errors
| Error | Fix |
|---|
nil pointer evaluating | Use with or {{ if .Values.x }} |
template "X" not defined | Check _helpers.tpl, prefix with chart name |
cannot unmarshal | Run helm lint, check YAML indentation |
| Whitespace issues | Use {{- and -}} to trim |
Debug workflow:
helm lint ./mychart
helm template test ./mychart --debug
helm install test ./mychart --dry-run=server
helm get manifest test
Related Skills
References