Validating Helm Chart Values with JSON Schemas
Helm v3 added support to validate values in a chart's values.yaml
file with JSON schemas. It allows us to do:
- Requirement checks. Example: An
API_KEY
environment variable is set - Type validation. Example: The image tag is a string such as
"1.5"
and not the number1.5
- Range validation. Example: The value for a CPU utilization percentage key is between 1 and 100
- Constraint Validation. Example: The
pullPolicy
isIfNotPresent
,Always
, orNever
; A URL has the formathttp(s)://<host>:<port>
In this post I'm going to show how to create a JSON schema and use it to validate a chart's values.yaml
file. After that I'm going to show how to automatically generate a schema from an existing values file.
Example
For this example I'm using the chart that is created when running helm create mychart
. We'll create a JSON schema that will validate that the following conditions are met:
image.repository
is a valid docker image nameimage.pullPolicy
isIfNotPresent
,Always
orNever
The relevant part in the values.yaml
file is:
image:
repository: my-docker-image
pullPolicy: IfNotPresent
The JSON schema needs to be in a file named values.schema.json
. It has to be located in the same directory as the values.yaml
file. To match the requirements from above the file needs to have the following content:
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"required": [
"image"
],
"properties": {
"image": {
"type": "object",
"required": [
"repository",
"pullPolicy"
],
"properties": {
"repository": {
"type": "string",
"pattern": "^[a-z0-9-_]+$"
},
"pullPolicy": {
"type": "string",
"pattern": "^(Always|Never|IfNotPresent)$"
}
}
}
}
}
Note that putting a key in the required
array does not mean that it has a value. In YAML if a key doesn't have a value it will be set to an empty string. To make sure the value was set, a regex for the pattern
key has to be added that matches a non-empty string.
To demonstrate that the validation is working I'm leaving the repo
empty and set pullPolicy
to an invalid value. Running lint shows the following output:
$ helm lint .
==> Linting .
[ERROR] values.yaml: - image.repository: Invalid type. Expected: string, given: null
- image.pullPolicy: Does not match pattern '^(Always|Never|IfNotPresent)$'
[ERROR] templates/: values don't meet the specifications of the schema(s) in the following chart(s):
mychart:
- image.repository: Invalid type. Expected: string, given: null
- image.pullPolicy: Does not match pattern '^(Always|Never|IfNotPresent)$'
Error: 1 chart(s) linted, 1 chart(s) failed
The schema is automatically validated when running the following commands:
- helm install
- helm upgrade
- helm lint
- helm template
The YAML values and the JSON schema need to be kept in sync manually. Helm will not check if keys from the YAML values file are missing from the schema. It will only validate fields that are specified in the schema.
Creating a JSON Schema for existing YAML values
We can infer a schema from existing YAML values and use it as a starting point when writing a new schema. The steps are:
- Convert your values YAML file to JSON on https://www.json2yaml.com/
- Paste the JSON on https://www.jsonschema.net/ and click on "Infer Schema"
- Paste the schema into the
values.schema.json
file
We can run helm lint
to make sure the schema has been generated correctly:
$ helm lint mychart/
==> Linting .
1 chart(s) linted, 0 chart(s) failed
The inferred schema will mark all keys as required and set their type. A regex can be added to keys to make sure they have a value set. The id
, title
, default
and examples
fields are not necessary for validating helm charts and can be removed.