Lab Guide
Three exercises: lint and fix a broken chart, add JSON Schema validation, and validate with kubeconform.
helm version). For Exercise 3, install kubeconform: brew install kubeconform (macOS) or download from GitHub releases.
Exercise 1
Lint and Fix a Broken Chart
In this exercise you will create a chart with intentional errors, use helm lint and helm template to find them, and fix each issue.
Step 1 — Create the chart scaffold
helm create lint-lab
cd lint-lab
Step 2 — Introduce errors
Open Chart.yaml and remove the version field entirely. Then open templates/deployment.yaml and introduce two errors:
# Error 1: wrong indentation on labels (remove 2 spaces)
metadata:
name: {{ include "lint-lab.fullname" . }}
labels: # <-- should be indented under metadata
{{- include "lint-lab.labels" . | nindent 4 }}
# Error 2: reference a non-existent value
spec:
replicas: {{ .Values.scaling.replicas }} # scaling doesn't exist
Step 3 — Run helm lint
helm lint . --strict
What to observe
- The missing
versionfield should produce an error - Note which issues lint catches and which it misses
Step 4 — Run helm template with debug
helm template test-release . --debug
The --debug flag will show the exact template and line number for the nil pointer error on .Values.scaling.replicas.
Step 5 — Fix all errors
- Add
version: 0.1.0back toChart.yaml - Fix the indentation of
labels:indeployment.yaml - Change
.Values.scaling.replicasto.Values.replicaCount
Step 6 — Verify
helm lint . --strict
helm template test-release . > /dev/null && echo "Template OK"
Success: Both commands exit with code 0 and no warnings.
Exercise 2
Add values.schema.json Validation
You will write a JSON Schema for the default Helm chart and test it against valid and invalid values.
Step 1 — Create the schema file
In the chart root (where Chart.yaml lives), create values.schema.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["replicaCount", "image", "service"],
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1,
"maximum": 10
},
"image": {
"type": "object",
"required": ["repository"],
"properties": {
"repository": {
"type": "string",
"minLength": 1
},
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"]
},
"tag": {
"type": "string"
}
}
},
"service": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["ClusterIP", "NodePort", "LoadBalancer"]
},
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535
}
}
}
}
}
Step 2 — Test with valid values
# Should succeed (default values.yaml matches the schema)
helm lint .
helm template test-release .
Step 3 — Test with invalid values
Create a file called bad-values.yaml:
replicaCount: "five"
image:
repository: ""
pullPolicy: Sometimes
service:
type: MeshService
port: 99999
helm lint . -f bad-values.yaml
What to observe
- Each violated constraint produces a distinct error message
- All violations are reported at once (Helm does not stop at the first)
- Note how the error messages map to your schema rules
Step 4 — Add a pattern constraint
Update the tag property in your schema to require semantic versioning:
"tag": {
"type": "string",
"pattern": "^v?[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.]+)?$"
}
Test with tag: latest (should fail) and tag: v1.2.3 (should pass).
Success: Schema rejects all invalid values and accepts valid ones.
Exercise 3
Validate with kubeconform
You will render the chart, pipe the output to kubeconform, and fix any schema violations.
Step 1 — Render and validate
# Render the chart
helm template test-release . > rendered.yaml
# Validate against K8s 1.29
kubeconform -strict -kubernetes-version 1.29.0 -summary rendered.yaml
Expected output
All resources should be valid if you are using the default helm create templates.
Step 2 — Introduce a schema error
Open templates/deployment.yaml and add a misspelled field:
spec:
template:
spec:
contianers: # <-- typo: should be "containers"
- name: {{ .Chart.Name }}
...
helm template test-release . | kubeconform -strict -kubernetes-version 1.29.0
What to observe
- kubeconform catches the misspelled field that
helm lintandhelm templateboth missed - The error message identifies the resource and the invalid property
Step 3 — Fix and re-validate
Correct the typo back to containers and run kubeconform again to confirm a clean pass.
Step 4 — Build a validation script
Create a script called validate.sh that runs the full pipeline:
#!/usr/bin/env bash
set -euo pipefail
CHART_DIR="${1:-.}"
echo "==> Linting..."
helm lint "$CHART_DIR" --strict
echo "==> Rendering templates..."
helm template validate-test "$CHART_DIR" > /tmp/rendered.yaml
echo "==> Validating against K8s schema..."
kubeconform -strict -kubernetes-version 1.29.0 -summary /tmp/rendered.yaml
echo "All checks passed."
chmod +x validate.sh
./validate.sh .
Success: The script runs all three stages and exits cleanly. Any single failure stops the pipeline.
helm install test-release . --dry-run=server --debug as a fourth stage in the script (requires a running cluster).