I would high recommend using a combination of the 2 solutions below.
Solution 1
Using a values.schema.json for imposing a structure on the values.yaml file.
Example:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"image": {
"description": "Container Image",
"properties": {
"repo": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"type": "object"
},
"name": {
"description": "Service name",
"type": "string"
},
"port": {
"description": "Port",
"minimum": 0,
"type": "integer"
},
"protocol": {
"type": "string"
}
},
"required": [
"protocol",
"port"
],
"title": "Values",
"type": "object"
}
(!) This schema will be applied to the values to validate it. Validation occurs when any of the following commands are invoked:
helm install
helm upgrade
helm lint
helm template
In order to add conditions to the validation - read in here.
(*) Further reading: Nice article.
Solution 2
There are cases when the code in values.schema.json
might be less readable when using conditions or we want to use a more dynamic logic into our validation.
In this case, we can create an validations.yaml
file (some vendors prefer using a .tpl
file) and add the validation logic using go templates.
Example:
If a specific feature (when enabled) needs an ip or a dns:
some_feature:
enabled: true
ip:
dns:
The validation logic can be written explicitly:
{{- if .Values.some_feature.enabled -}}
{{- if and (not .Values.some_feature.ip ) (not .Values.some_feature.dns ) -}}
When some_feature is enabled, ip or dns must be given.
{{- end -}}
{{- end -}}
(*) This logic could also be writen using json-schema if-else statement, but it might be less readable.
(**) Consider placing all validations under a /tests
or /validations
folder where all tests are devided into seperated files (like unit tests).