1
votes

Is there a way to test that the templating works fine for all the possible values?
(note: this is different from helm test which is used for testing the deployed chart through arbitrary code ran in a job).

What I would like to achieve is iterating over a set of values and checking the generated K8s resources for each.

Lets say we want to test whether our chart is correctly written:

The chart:
Values.yaml

app:
  port: 8081

pod2:
   enabled: true

AppPod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: AppPod
  labels:
    app: nginx
spec:
...
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: {{ $.Values.app.port| default 8080  }}

Pod2.yaml

{{- if $.Values.pod2.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: Pod2
  labels:
    app: nginx2
spec:
...
{{- end}}

We want to run the following tests:

  • with the default Values.yaml -> assert port=8081 and Pod2 is created
  • With app.port missing -> assert port=8080
  • With pod2.enabled false -> assert Pod2 is not created
  • With pod2 missing -> test will fail because the key 'pod2' is mandatory

So basically to test the templating logic.

What I am doing right now:
Whenever I modify something in the chart I just run helm template for different Values.yaml and check the results by hand. Doing this by hand is error prone and it becomes more time consuming the more template the chart contains.

Is there any builtin helm feature or a separate framework for this?

1

1 Answers

0
votes

Yes, we do that with rego policy rules. The set-up is not complicated, this is how it looks as part of one of the pipeline of ours (this is a very simplified example to get you started):

# install conftest to be able to run helm unit tests
wget https://github.com/open-policy-agent/conftest/releases/download/v0.28.1/conftest_0.28.1_Linux_x86_64.tar.gz
tar xzf conftest_0.28.1_Linux_x86_64.tar.gz
chmod +x conftest

# you can call "helm template" with other override values of course, too
helm template src/main/helm/my-service/ > all.yaml

echo "running opa policies tests"
if ! ./conftest test -p src/main/helm/my-service/ all.yaml; then
  echo "failure"
  exit 1
fi

inside my-service directory there is a policy folder that holds the "rules" for testing (though this can be passed as an argument). Here is an example of two rules that I had to very recently write:

package main

deny_app_version_must_be_present[msg] {
    input.kind == "Deployment"
    env := input.spec.template.spec.containers[_].env[_]
    msg := sprintf("env property with name '%v' must not be empty", [env.name])
    "APP_VERSION" == env.name ; "" == env.value
}

deny_app_version_env_variable_must_be_present[msg] {
    input.kind == "Deployment"
    app_version_names := { envs | envs := input.spec.template.spec.containers[_].env[_]; envs.name == "APP_VERSION"}
    count(app_version_names) != 1
    msg := sprintf("'%v' env variable must be preset once", ["APP_VERSION"])
}

This validates that the container in the Deployment has an env variable called APP_VERSION that must be unique and must be non-empty.