Skip to content

Y0-L0/helm-snoop

Repository files navigation

helm-snoop

CI codecov Quality Gate Status Vulnerabilities Bugs Code Smells Go Report Card Release License: AGPL-3.0 Homebrew pre-commit hook

helm-snoop keeps your config and docs in your values.yaml and (in the future) schema.json in sync with the code in your helm template files.
It parses the values.yaml and template files of helm charts and finds undefined and unused values.

Beta Status: Expect some false positives and breaking changes as the project matures.

πŸš€ Getting Started

🐳 Try it out

docker run --rm -v $(pwd):/chart ghcr.io/y0-l0/helm-snoop:latest /chart

πŸ“¦ Installation

Homebrew (macOS/Linux):

brew install y0-l0/tap/helm-snoop

APT (Debian/Ubuntu):

echo "deb [trusted=yes] https://apt.fury.io/stadimeter/ /" \
  | sudo tee /etc/apt/sources.list.d/fury.list
sudo apt update && sudo apt install helm-snoop

Binary (Linux amd64):

VERSION=0.7.0
curl -fsSL "https://github.com/y0-l0/helm-snoop/releases/download/v${VERSION}/helm-snoop_${VERSION}_linux_amd64.tar.gz" | tar -xz
sudo mv helm-snoop /usr/local/bin/

πŸ’» Usage

# Analyze a chart directory or archive
helm-snoop ./my-chart/
helm-snoop ./my-chart-0.1.0.tgz

# Include additional values files
helm-snoop --values ./env-values.yaml --values ./secrets-values.yaml ./my-chart/

# Suppress specific findings
helm-snoop --ignore .image.tag --ignore .config.* ./my-chart/

# JSON output
helm-snoop --json ./my-chart

Analyzes Helm charts and reports:

  • Unused: Keys defined in values files but never referenced in templates
  • Undefined: Paths referenced in templates but not defined in any values file

See docs/CLI.md for the complete cli flag documentation.

βœ… Features

  • Variable tracking: Variables are tracked across references (e.g., {{ $var := .Values.foo }}{{ $var.bar }})
  • Context-aware path resolution: Correctly resolves relative paths within with and range contexts (e.g., .Values.config β†’ with β†’ .timeout resolves to .Values.config.timeout)
  • Dict/list operations: Tracks values through dict, list, merge, concat operations
  • Nested template definitions: Follows define blocks across multiple files
  • Include/Template functions: Template includes are followed and analyzed
  • Wildcard ignore patterns: Advanced pattern matching for suppressing specific warnings
  • Control flow: All branches of if/else blocks are analyzed

⚠️ Limitations

  • Limited tpl function support: Dynamic template strings have partial support
  • No schema.json validation: Only compares templates against values.yaml, not against schema definitions
  • Limited dynamic evaluation: Complex patterns like {{ index .Values.a .Values.b }} may not be fully resolved
  • No subchart analysis: Does not analyze subcharts (only collects template functions via define)
  • No global values from subcharts: May report false positives for undefined global paths from subcharts

πŸͺ pre-commit / prek

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/y0-l0/helm-snoop
    rev: v0.7.0
    hooks:
      - id: helm-snoop        # requires helm-snoop on PATH
      # - id: helm-snoop-docker  # uses Docker instead

Two hooks are available: helm-snoop (requires the binary on $PATH) and helm-snoop-docker (runs via ghcr.io/y0-l0/helm-snoop). Changed files are resolved to their parent chart directories automatically.

In monorepos with multiple charts, consider adding the hook once per chart with a scoped files regex. This keeps flags like -i within the chart boundaries.

πŸ” Background

🎯 The Problem

Golang doesn't compile with undefined or unused variables. Helm has no such checks.

In my day job, my team maintains 50_000 lines of helm chart code.

The majority of bugs in these helm charts are:

  • Typos in either template files or values.yaml files
  • Mismatches between defaults/documentation in values.yaml and actual template implementation

It is also close to impossible to keep the documentation in values.yaml in sync with the actual template implementation. New config options are implemented but never documented. Old config options are never removed from the documentation.

All of these could be detected by a Helm Chart linter using static analysis:

  • No undefined values - .Values.* paths require defaults and documentation in values.yaml
  • No unused values - No outdated or misspelled keys in values.yaml

helm-snoop is (trying to become) that linter.

πŸ”— Related Tools

helm-unused-values Similar PoC implementation, appears unfinished and inactive since some time.

Regex-based tools Limited by their approach; can't handle complex template logic.

JSON Schema for values.yaml Validates user input, which is valuable. However, it suffers from the same sync problem: if your schema.json is out of sync with your template implementation, users can't configure those out-of-sync properties.

For detailed comparison, see docs/RESEARCH.md

🀝 Contributing

Contributions would be wonderful:

  • Architecture input, especially from Helm codebase experts
  • Testing and user feedback
  • Code quality and idiomatic Go (inexperienced gopher here!)

About

helm-snoop can detect drift between the values.yaml file and the helm template files. Making sure the documentation matches the implementation and protecting from typos.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors