A Helm plugin that uses Common Expression Language (CEL) to validate values. Instead of using JSON Schema in values.schema.json
, you can write more expressive validation rules using CEL in values.cel.yaml
.
helm plugin install https://github.com/idsulik/helm-cel
Create a values.cel.yaml
file in your chart directory alongside your values.yaml
file:
rules:
- expr: "has(values.service) && has(values.service.port)"
desc: "service port is required"
- expr: "values.service.port >= 1 && values.service.port <= 65535"
desc: "service port must be between 1 and 65535"
- expr: "!(has(values.replicaCount)) || values.replicaCount >= 1"
desc: "if replicaCount is set, it must be at least 1"
Then run validation:
helm cel /path/to/your/chart
Given this values.yaml
:
service:
type: ClusterIP
port: 80
replicaCount: 1
image:
repository: nginx
tag: latest
And this values.cel.yaml
:
rules:
- expr: "has(values.service) && has(values.service.port)"
desc: "service port is required"
- expr: "values.service.port >= 1 && values.service.port <= 65535"
desc: "service port must be between 1 and 65535"
- expr: "values.replicaCount >= 1"
desc: "replica count must be at least 1"
- expr: |
has(values.image) &&
has(values.image.repository) &&
has(values.image.tag)
desc: "image repository and tag are required"
If validation fails, you'll get a clear error message:
❌ Validation failed: replica count must be at least 1
Rule: values.replicaCount >= 1
Path: replicaCount
Current value: 0
Each rule in values.cel.yaml
consists of:
expr
: A CEL expression that should evaluate totrue
for valid valuesdesc
: A description of what the rule validates
CEL expressions have access to the entire values structure through the values
variable. Some useful CEL functions:
has(values.path)
- checks if a field existstype(value)
- returns the type of a valuesize(list)
- returns the length of a list or map
- Required fields:
- expr: "has(values.fieldName)"
desc: "fieldName is required"
- Value constraints:
- expr: "values.number >= 0 && values.number <= 100"
desc: "number must be between 0 and 100"
- Conditional requirements:
- expr: "!(has(values.optional)) || values.optional >= 0"
desc: "if optional is set, it must be non-negative"
- Type validation:
- expr: "type(values.ports) == list"
desc: "ports must be a list"
- Complex object validation:
- expr: |
has(values.container) &&
has(values.container.image) &&
has(values.container.tag)
desc: "container must have image and tag"
Requirements:
- Go 1.20 or later
Build:
make build
Install locally:
make install
Run tests:
make test
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.