Skip to content

Validate Config

It is frustrating when bad config makes it all the way to production. "Bad" config can range from the annoying (whitespace causing a deploy failure) to the catastrophic (pointing to the wrong database).

ConfigHub prevents bad config from reaching production with a flexible system for validating config and gating applies when validation fails.

Validating triggers

Validation is done by adding validating triggers to a space. Jump to the background section to read more about the various types of triggers.

Validate the config format

Let's add a validation trigger to the tutorial space that checks if the config data conforms to Kubernetes schema. vet-schemas is a function that does just that:

cub trigger create --space tutorial valid-k8s Mutation Kubernetes/YAML vet-schemas

A validating trigger will fire when units change and it will place an apply gate if the validation fails. Let's test this by making a non-conforming change to chatapp-dev:

cub run yq-i --unit chatapp-dev '.badspec.field = "value"'

This will add a badspec top level entry in the yaml structure. You can see what it did with:

cub unit diff -u chatapp-dev --from=-1

Now let's look at the unit list:

cub unit list --columns Name,ApplyGates

You should see something like:

NAME            APPLY-GATES           
chatapp-dev     valid-k8s/vet-schemas    
chatapp-prod    None

This indicates that chatapp-dev has a problem that must be fixed before it can be applied. If you try to apply:

cub unit apply chatapp-dev

You will get an error saying the unit has outstanding apply gates. To fix the problem you can restore a previous revision or you can delete the bad element with:

cub run yq-i --unit chatapp-dev 'del(.badspec)'

Validate security posture

In addition to checking for syntax problems, you can also validate that a unit meets certain standards. For example, you may require that all containers run as non-root. You can enforce this with a validating trigger that uses the vet-celexpr function:

cub trigger create ensure-nonroot Mutation Kubernetes/YAML vet-celexpr \
    "r.kind != 'Deployment' || (r.spec.template.spec.securityContext.runAsNonRoot == true)"

This trigger will fail if a unit has a Deployment resource and the resource does not have runAsNonRoot set to true.

Note

Existing units will not be affected by a newly created trigger until they are changed. This limitation will be addressed in the future.

To see the effect of this trigger, let's create a new unit as a clone:

cub unit create chatapp-prod2 --upstream-unit chatapp-dev

Now if you run

cub unit list --columns Name,ApplyGates

You'll see:

NAME             APPLY-GATES                
chatapp-dev      None
chatapp-prod     None                          
chatapp-prod2    ensure-nonroot/vet-celexpr

To fix this, you can use a convenience function that sets sensible security defaults:

cub run set-pod-defaults --unit chatapp-prod2 --security-context true

Now if you check the unit list, the apply gate should be gone. You can see what the function did with a diff:

cub unit diff -u chatapp-prod2 --from=-1

You will see that the function made several improvements, including setting runAsRoot to false.

Summary

  • Validating triggers makes it easy to prevent broken or non-compliant configuration from being applied.
  • Validating triggers set Apply Gates when the validation fails.
  • Units cannot be applied until Apply Gates have been cleared by fixing the problem in the config data.
  • Validating triggers are simply function invocations which makes them very flexible. You can write your own function from scratch if you have a specific need that is not met by standard functions.
  • Validating triggers are set on a space and apply to all units in the space.

Next

Manage drift

Further reading