Comprehensive toolkit for validating, linting, testing, and analyzing Helm charts and their rendered Kubernetes resources. Use this skill when working with Helm charts, validating templates, debugging chart issues, working with Custom Resource Definitions (CRDs) that require documentation lookup, or checking Helm best practices.
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
This skill provides a comprehensive validation and analysis workflow for Helm charts, combining Helm-native linting, template rendering, YAML validation, schema validation, CRD documentation lookup, and security best practices checking.
IMPORTANT: This is a READ-ONLY validator. It analyzes charts and proposes improvements but does NOT modify any files. All proposed changes are listed in the final summary for the user to review and apply manually or via the helm-generator skill.
Follow this sequential workflow. Each stage catches different types of issues.
bash scripts/setup_tools.shRequired: helm (v3+), yamllint, kubeconform, kubectl (optional). If tools are missing, provide installation instructions and ask the user before proceeding.
bash scripts/validate_chart_structure.sh <chart-directory>Validates required files (Chart.yaml, values.yaml, templates/) and recommended files (_helpers.tpl, NOTES.txt, .helmignore).
helm lint <chart-directory> --strict
# Optional: --values <file>, --set key=value, --debughelm template <release-name> <chart-directory> \
--values <values-file> \
--debug \
--output-dir ./renderedUseful flags: --validate, --include-crds, --is-upgrade, --kube-version 1.28.0, --show-only templates/<file>.yaml.
yamllint -c assets/.yamllint ./rendered/*.yamlFix template-generated YAML issues in the source template, not the rendered output.
bash scripts/detect_crd_wrapper.sh <chart-directory>/crds/*.yaml
bash scripts/detect_crd_wrapper.sh ./rendered/*.yamlOutput:
[{"kind": "Certificate", "apiVersion": "cert-manager.io/v1", "group": "cert-manager.io", "version": "v1", "isCRD": true}]For each detected CRD:
Try context7 MCP first (preferred):
mcp__context7__resolve-library-id with the CRD project name (e.g. "cert-manager")mcp__context7__get-library-docs with the resolved ID, topic (e.g. "Certificate spec"), tokens: 5000Fallback to WebSearch:
"<Kind>" "<group>" kubernetes CRD "<version>" documentation specExtract required fields, types, validation rules, and version-specific deprecations.
kubeconform \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
-summary -verbose \
./rendered/*.yamlAdd -strict for production, -ignore-missing-schemas for internal CRDs, -kubernetes-version 1.28.0 for version pinning. "No schema found" for CRDs is expected, validate those manually using Stage 6 docs.
helm install <release-name> <chart-directory> --dry-run --debug --values <values-file>
helm upgrade <release-name> <chart-directory> --dry-run --debug --values <values-file>
# With helm-diff plugin:
helm diff upgrade <release-name> <chart-directory>Catches admission controller rejections, policy violations, quota issues, and webhook errors. Skip and document if no cluster access.
Analyze rendered Deployment/Pod templates:
grep -l "securityContext" ./rendered/*.yaml
grep -l "resources:" ./rendered/*.yaml
grep "image:.*:latest" ./rendered/*.yamlRequired checks:
runAsNonRoot, runAsUser, fsGroupallowPrivilegeEscalation: false, readOnlyRootFilesystem, capabilities.drop: [ALL]:latest image tagsThis stage is MANDATORY even if all validations pass.
Read references/helm_best_practices.md
Read references/k8s_best_practices.md| Stage | Status | Issues |
|-------|--------|--------|
| 1. Tool Check | ✅ Passed | All tools available |
| 2. Structure | ⚠️ Warning | Missing: .helmignore |
| 3. Helm Lint | ✅ Passed | 0 errors |
| 4. Template Render | ✅ Passed | 5 templates rendered |
| 5. YAML Syntax | ✅ Passed | No errors |
| 6. CRD Detection | ✅ Passed | 1 CRD documented |
| 7. Schema Validation | ✅ Passed | All resources valid |
| 8. Dry-Run | ✅ Passed | No cluster errors |
| 9. Security Check | ⚠️ Warning | Missing securityContext |:latest tag, missing recommended filesFor each issue:
Common fixes:
_helpers.tpl: bash scripts/generate_helpers.sh <chart>.helmignore: Copy from assets/.helmignorevalues.schema.json: Copy/customize from assets/values.schema.jsoninclude instead of template for pipeline supportnindent for proper YAML indentationdefault function for optional valuesrequired for critical values## Validation Summary
**Chart:** <chart-name>
**Status:** ⚠️ Warnings Found (or ✅ Ready for Deployment)
**Issues:** Errors: X Warnings: Y Info: Z
**Proposed Changes:** N changes recommended
**Next Steps:**
1. Review proposed changes above
2. Apply manually or use helm-generator skill
3. Re-run validation to confirm fixesFor complex templating tasks, load the dedicated reference:
Read references/template_functions.mdStandard helper patterns (templates/_helpers.tpl), including fullname, labels, and selectorLabels definitions, are documented in references/template_functions.md.
Key template functions: required, default, quote, include, tpl, toYaml, merge, lookup, see references/template_functions.md for full reference with examples.
Symptom: Helm reports "Chart.yaml file is missing" even though the file exists.
Diagnosis & Fix:
xattr /path/to/chart/Chart.yaml # check for attributes
xattr -cr /path/to/chart/ # remove all recursivelyPrevention: Use helm create as a base, or create files with shell heredocs (cat > file << 'EOF').
scripts/setup_tools.sh, skip optional stages, document what was skipped.--debug.kubectl apply --dry-run=server -f ./rendered/, document limitations.kubectl explain <kind>.apiVersion: v2 in Chart.yaml (Helm 3+)kubectl api-versions to list available API versionskubeVersion constraint in Chart.yaml when needed--kube-version in helm template / kubeconformhelm lint passing as sufficient validationWHY: helm lint only checks chart structure and basic YAML syntax; it does not validate rendered Kubernetes manifests against the API schema.
BAD: Ship a chart after helm lint passes with no manifest validation.
GOOD: Run helm template | kubeval or helm template | kubeconform to validate rendered output.
--set overrides when linting complex chartsWHY: Linting with only default values misses validation errors that only surface when required values are provided.
BAD: helm lint ./chart with no value overrides.
GOOD: helm lint ./chart --set image.tag=v1.0 --set ingress.enabled=true to exercise non-default code paths.
helm diff output before helm upgradeWHY: Upgrading without reviewing the diff can silently delete resources (e.g., removing a service selector key).
BAD: Run helm upgrade directly in CI without diffing.
GOOD: Run helm diff upgrade myapp ./chart and fail the pipeline if destructive changes are detected.
WHY: helm dependency update failure silently falls back to cached or missing sub-charts, producing incorrect renders.
BAD: Run helm template ./chart without first running helm dependency update.
GOOD: Always run helm dependency update && helm template in sequence.
WHY: The validator is read-only by design. Unreviewed edits can change a release in ways the user did not approve.
BAD: Edit values.yaml to add a missing securityContext as soon as the check fails.
GOOD: List the change as a proposed before/after block in the final summary for the user to apply, manually or with the helm-generator skill.
WHY: Rendered files are regenerated on every run, so a fix applied there is lost and the template defect remains.
BAD: Hand-edit ./rendered/deployment.yaml to clear a yamllint error.
GOOD: Fix the issue in the source template under templates/ and re-render.
WHY: Stage 10 is mandatory; the summary table is the record of what ran and what was skipped, and a silent pass hides skipped stages.
BAD: Say "chart looks fine" after lint succeeds.
GOOD: Produce the validation summary table and final summary even when every stage passes.
:latest image tagWHY: :latest makes deployments non-reproducible, so the same chart can run different images over time.
BAD: image: nginx:latest in a rendered Deployment.
GOOD: Pin an explicit version tag, for example image: nginx:1.27, and report any :latest tag as a warning.
WHY: kubeconform reports "No schema found" for CRDs it cannot check, which means the resource was not validated, not that it is valid.
BAD: Count a Certificate resource as validated because kubeconform raised no error.
GOOD: Look up the CRD documentation (Stage 6) and check required fields manually, using -ignore-missing-schemas only for the schema step.
WHY: Each stage catches a different class of issue; stopping early hides later problems and forces repeated runs.
BAD: Stop after helm lint fails and report one error.
GOOD: Continue to the next stage, collect all errors, and present them together in Stage 10.
setup_tools.sh: Check/install required toolsvalidate_chart_structure.sh: Validate chart directory structuredetect_crd_wrapper.sh: Detect CRDs in YAML files (manages Python venv)detect_crd.py: Parse YAML to identify CRDs, output JSONgenerate_helpers.sh: Generate standard _helpers.tplhelm_best_practices.md: Chart structure, template conventions, values organizationk8s_best_practices.md: Metadata, labels, resource limits, security contexttemplate_functions.md: All built-in Helm/Sprig functions with examples, standard helper patterns.helmignore: Standard ignore patterns for chart packaging.yamllint: Pre-configured yamllint rules for Kubernetes YAMLvalues.schema.json: Example JSON Schema template for values validationpantheon-org/tekhne
eefa132
Also appears in
last in sync Aug 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.