We’ve already seen how CUE makes it trivially easy to get started, in
Checking existing Kyverno policy files using CUE.
That guide finished by showing us how to validate multiple data files using
specifically constructed cue
commands … but wouldn’t it be useful if CUE
could track which data files need to be validated against which schemas,
and then perform all those checks at once? This guide demonstrates how
to start offloading that work to CUE.
Start with a directory containing several policy files
Our example setup begins with a kyverno-policies
directory that contains two
unrelated Kyverno policy files:
# filepath: kyverno-policies/require-labels.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
annotations:
policies.kyverno.io/title: Require Labels
policies.kyverno.io/category: Best Practices
policies.kyverno.io/description: >-
Define and use labels that identify semantic attributes of your application or Deployment.
spec:
validationFailureAction: Audit
background: true
rules:
- name: check-for-labels
match:
any:
- resources:
kinds:
- Pod
validate:
message: "The label `app.kubernetes.io/name` is required."
pattern: {metadata: {labels: {app.kubernetes.io/name: "?*"}}}
# filepath: kyverno-policies/require-pod-requests-limits.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-requests-limits
annotations:
policies.kyverno.io/title: Require Limits and Requests
policies.kyverno.io/category: Best Practices, EKS Best Practices
policies.kyverno.io/description: >-
This policy validates that all containers have something specified for memory and CPU
requests and memory limits.
spec:
validationFailureAction: Audit
background: true
rules:
- name: validate-resources
match: {any: [{resources: {kinds: [Pod]}}]}
validate:
message: "CPU and memory resource requests and memory limits are required for containers."
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
=(initContainers):
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
=(ephemeralContainers):
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
These policies are adapted from Kyverno’s
policies
repository, but you should use policies that are more relevant to your
situation.
Initialise your local CUE module
CUE that uses modules from the Central Registry, as shown below, needs to exist within its own CUE module:
$ cue mod init cue.example
You can choose any module name you like - it’s easy to change it later.
Embed the policy files in some CUE
CUE’s file embedding
allows the cue
command to read data files without being told about them through
individual arguments. The following CUE enables this feature, and then embeds
the Kyverno policy files shown above:
// filepath: kyverno.cue
@extern(embed) // File embedding must be explicitly enabled.
package config
import "cue.dev/x/kyverno/clusterpolicy/v1"
kyverno: {
// Embed the contents of all YAML policy files.
clusterPolicies: _ @embed(glob=kyverno-policies/*.yaml)
// Validate the contents of each embedded file against the relevant schema.
clusterPolicies: [_]: v1.#ClusterPolicy
}
Tidy your local CUE module
Always use
cue mod tidy
when you use a CUE module for the first time:
$ cue mod tidy
Tidying a module is an important part of using curated modules from the Central Registry.
If you see an error message mentioning “too many requests” while following this guide, then login to the Central Registry and re-run the failing command. The Central Registry allows more requests from authenticated users.
Validate the policy files
$ cue vet -c
We know that each of our embedded policy files has a valid structure because this command doesn’t display any errors.
This simple cue
command performs all the same checks as
the previous guide,
and is also somewhat easier to remember and repeat –
but that’s not the only reason to choose file embedding.
As we’ll see in later guides, using this feature opens the door towards
managing a truly unified configuration graph …
Next steps
Validating your existing configuration files with CUE can help make development and deployments safer, but defining those same files in CUE lets you build on its first-class templating, referencing, and policy features. Take the first step with Getting started with Kyverno + CUE …