# Helm Debugging Tips ## Rendering and Validation ### Dry-run with debug output ```bash helm install myapp ./mychart --dry-run --debug ``` This renders templates locally without installing, showing you the exact manifests that would be deployed. ### Template rendering only ```bash helm template myapp ./mychart --debug ``` Useful for piping output to other tools or grepping for specific values. ### Helm Template vs Helm Install Dry-Run: Key Differences #### `helm template` - **Runs locally** - doesn't connect to Kubernetes API - **No cluster validation** - can't check if resources would actually work - **No release creation** - doesn't create a release object - **Faster** - no network calls - **Works offline** - doesn't need a cluster connection - **Can't use `lookup` function** - since there's no cluster to query #### `helm install --dry-run --debug` - **Connects to cluster** - communicates with Kubernetes API server - **Validates resources** - checks if API versions exist, CRDs are installed, etc. - **Creates release (in memory)** - simulates the full release process - **Checks RBAC** - validates permissions - **Slower** - network overhead - **Requires cluster access** - **Can use `lookup` function** - queries live cluster data #### When to Use Each **Use `helm template` when:** - You want quick feedback on template rendering - You're working offline or don't have cluster access - You want to pipe output to other tools (kubectl, yq, etc.) - You're debugging pure template logic issues - You want to see rendered manifests without any cluster interaction **Use `helm install --dry-run --debug` when:** - You want to validate against actual cluster state - You need to test RBAC permissions - Your templates use the `lookup` function - You want to catch API version mismatches - You're doing final validation before actual deployment - You want to see exactly what would happen during installation - ### Validate against a live cluster ```bash helm install myapp ./mychart --dry-run --debug --validate ``` This performs server-side validation, catching issues like missing CRDs or API versions. ## Inspecting Releases ### Get all values (computed + defaults) ```bash helm get values myapp --all ``` Shows the complete merged values, not just what you overrode. ### See the actual manifests deployed ```bash helm get manifest myapp ``` Shows exactly what's running in your cluster, useful for comparing with what you expected. ### Check release history ```bash helm history myapp ``` See all revisions and their statuses. ## Advanced Template Debugging ### Use `fail` function for complex sanity checks ```yaml {{- if and not .Values.image.tag not eq .Values.image.tag "latest" }} {{- fail "image.tag is required, it may not be set to latest" }} {{- end }} ``` ### Debug specific template files ```bash helm template myapp ./mychart -s templates/deployment.yaml ``` The `-s` flag renders only specific templates. ### Inspect computed values in templates ```yaml {{ toYaml .Values }} ``` Temporarily add this to see the full values structure. ## Troubleshooting Failed Installs ### Check release status (in all namespaces) ```bash helm list -A helm status myapp ``` ### Force delete stuck releases ```bash helm delete myapp --no-hooks kubectl delete secret -n <namespace> sh.helm.release.v1.myapp.v<number> ``` ### Disable hooks for debugging ```bash helm install myapp ./mychart --no-hooks ``` Hooks can cause mysterious failures; this bypasses them. ## Linting and Best Practices ### Comprehensive lint ```bash helm lint ./mychart --strict --with-subcharts ``` Catches template errors, warning and chart structure issues. ### Use values schema (values.schema.json) Define a JSON schema to validate user-provided values at install time. ## Pro Tips 1. **Use `--create-namespace`** to avoid "namespace not found" errors 2. **Keep `_helpers.tpl` clean** - complex logic there is hard to debug 3. **Use `lookup` function carefully** - it queries the cluster during rendering and can cause unexpected behavior 4. **Enable verbose output** with `-v` flag (up to `-vvv` for maximum verbosity) 5. **Test with different Kubernetes versions** using `--kube-version` flag in dry-run mode ## Additional Resources - [Helm Documentation](https://helm.sh/docs/) - [Helm Template Language](https://helm.sh/docs/chart_template_guide/) - [Debugging Charts](https://helm.sh/docs/chart_template_guide/debugging/)