kustomize doesn't validate either its input or output beyond the validation provided by the marshalling/unmarshalling packages it depends on.
Another tool, kubeval, goes beyond this to do k8s aware validation. Here's a usage example:
$ kubeval my-invalid-rc.yaml
The document my-invalid-rc.yaml contains an invalid ReplicationController
--> spec.replicas: Invalid type. Expected: integer, given: string
One can write a Kustomize transformer plugin to run kubeval against the resources that have been loaded by Kustomize.
Make a place to work:
DEMO_HOME=$(mktemp -d)
mkdir -p $DEMO_HOME/valid
mkdir -p $DEMO_HOME/invalid
PLUGINDIR=$DEMO_HOME/kustomize/plugin/someteam.example.com/v1/validator
mkdir -p $PLUGINDIR
Download the kubeval binary depending on the operating system and add it to $PATH.
OS=`uname | sed -e 's/Linux/linux/' -e 's/Darwin/darwin/'`
wget https://github.com/instrumenta/kubeval/releases/download/0.9.2/kubeval-${OS}-amd64.tar.gz
tar xf kubeval-${OS}-amd64.tar.gz
export PATH=$PATH:`pwd`
Kustomize has the following assumption of a transformer plugin:
- The resources are passed to the transformer plugin from stdin.
- The configuration file for the transformer plugin is passed in as the first argument.
- The working directory of the plugin is the kustomization directory where it is used as a transformer.
- The transformed resources are written to stdout by the plugin.
- If the return code of the transformer plugin is non zero, Kustomize regards there is an error during the transformation.
A transformer plugin for the validation can be written as a bash script, which execute the kubeval binary and return proper output and exit code.
cat <<'EOF' > $PLUGINDIR/Validator
#!/bin/bash
if ! [ -x "$(command -v kubeval)" ]; then
echo "Error: kubeval is not installed."
exit 1
fi
temp_file=$(mktemp)
output_file=$(mktemp)
cat - > $temp_file
kubeval $temp_file > $output_file
if [ $? -eq 0 ]; then
cat $temp_file
rm $temp_file $output_file
exit 0
fi
cat $output_file
rm $temp_file $output_file
exit 1
EOF
chmod +x $PLUGINDIR/Validator
Define a kustomization containing a valid ConfigMap and the transformer plugin.
cat <<'EOF' >$DEMO_HOME/valid/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm
data:
foo: bar
EOF
cat <<'EOF' >$DEMO_HOME/valid/validation.yaml
apiVersion: someteam.example.com/v1
kind: Validator
metadata:
name: notImportantHere
EOF
cat <<'EOF' >$DEMO_HOME/valid/kustomization.yaml
resources:
- configmap.yaml
transformers:
- validation.yaml
EOF
Define a kustomization containing an invalid ConfigMap and the transformer plugin.
cat <<'EOF' >$DEMO_HOME/invalid/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm
data:
- foo: bar
EOF
cat <<'EOF' >$DEMO_HOME/invalid/validation.yaml
apiVersion: someteam.example.com/v1
kind: Validator
metadata:
name: notImportantHere
EOF
cat <<'EOF' >$DEMO_HOME/invalid/kustomization.yaml
resources:
- configmap.yaml
transformers:
- validation.yaml
EOF
The directory structure is as the following:
/tmp/tmp.fAYMfLZJs4
├── invalid
│ ├── configmap.yaml
│ ├── kustomization.yaml
│ └── validation.yaml
├── kustomize
│ └── plugin
│ └── someteam.example.com
│ └── v1
│ ├── kubeval
│ └── Validator
└── valid
├── configmap.yaml
├── kustomization.yaml
└── validation.yaml
Define a helper function to run kustomize with the correct environment and flags for plugins:
function kustomizeBd {
XDG_CONFIG_HOME=$DEMO_HOME \
kustomize build \
--enable_alpha_plugins \
$DEMO_HOME/$1
}
Build the valid variant
kustomizeBd valid
The output contains a ConfigMap as
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: cm
Build the invalid variant
kustomizeBd invalid
The output is an error as
data: Invalid type. Expected: object, given: array
rm -rf $DEMO_HOME