Monokle-CLI: Flexible Kubernetes YAML Validation

Ole Lensmar
Kubeshop
7 min readDec 20, 2022

--

The importance of validation of your Kubernetes YAMLs as part of your pre-commit/deploy workflows is evident as the adoption of GitOps-based workflows grows. Performing validations later in your workflows — as part of your PR process or even in-cluster as validation Webhooks is a valuable practice, but should perhaps be seen more as a safety net than as the primary method to enforce the quality of your YAMLs. Validating early in your development workflows decreases turnaround times from hours/minutes to seconds — instead of having to wait for your PR-bot or GitOps reconciler to tell you things don’t seem right — your local tooling tells you before you commit or deploy anything.

A fancy way of describing this focus on pre-deployment quality is “shift-left” — and a variety of tools for pre-commit/deploy validation are available — unfortunately none of them provide the flexibility and power on their own that platform engineers need to provide guard-rails for their development teams to deliver high-quality deployments in line with corporate or team guidelines — and a lot of time ends up being spent on building custom solutions and/or resorting to post-deployment quality enforcement.

What is Monokle-CLI?

In our ongoing efforts to provide K8s engineers with a consistent toolchain to achieve pre-deployment quality, we have extracted the core validation logic from our popular Monokle Desktop tool — beefed it up with powerful configuration and extension mechanisms — and packaged it in a CLI and GitHub action to provide you with a one-stop solution to validate your Kubernetes YAMLs, consistently across teams and workflows, before you commit or deploy them to your cluster(s).

To that end, Monokle-CLI can be leveraged out-of-the-box to validate:

  • YAML syntax
  • The schemas of your YAMLs against a configurable K8s version
  • Links/references between Kubernetes resources
  • A set of predefined OpenPolicyAgent (OPA) policies targeting security and resource-allocation best practices
  • Custom rules written in typescript

Monokle-CLI automatically configures all of the validators listed above through an es-lint inspired configuration approach. This configuration is honoured by the cli as well as the corresponding GitHub Action and will soon carry over to other tools in our ecosystem including Monokle Cloud and Monokle Desktop.

As with other tools in the Monokle ecosystem, Monokle-CLI is 100% open-source — MIT licensed.

Jumping in…

Enough talk — let’s jump straight in. If you’re on MaxOS, install Monokle-CLI with bre

brew install kubeshop/monokle/monokle-cli

on other platforms you’ll need npm installed for now:

npm install - global @monokle/cli

Switch to a folder containing Kubernetes manifests and run the validator

monokle validate <file/folder containing manifests>

We’ll use the standalone deployment example from the monokle-demo repo going forward:

As you can see, we immediately found a bunch of errors — let’s create a monokle.validation.yaml config file to disable these OPA-related errors since they don’t really apply to us, and add the correct k8s schema version for the schema validation:

plugins: 
kubernetes-schema: true
open-policy-agent: true
rules:
open-policy-agent/no-elevated-process: false
open-policy-agent/drop-capabilities: false
open-policy-agent/cpu-limit: false
open-policy-agent/run-as-non-root: false
open-policy-agent/no-latest-image: false
open-policy-agent/cpu-request: false
open-policy-agent/memory-request: false
open-policy-agent/memory-limit: false
open-policy-agent/no-low-user-id: false
open-policy-agent/no-low-group-id: false
open-policy-agent/no-writable-fs: false
settings:
kubernetes-schema:
schemaVersion: v1.22.3

Run the command again.

Much better! All validator plugins and their settings and rules are documented on GitHub.

Integrating with CI / CD

Ensuring that your configured rules are honoured before you merge your changes is a good safety net to catch rogue commits and YAML delinquents! Monokle-CLI can of course easily be configured to run as part of your pipelines. If you’re on GitHub, the monokle-github-action is a convenient way to ensure validation as part of your PR validations:

on: push

jobs:
validate:
name: Validate Kubernetes resources with Monokle
runs-on: ubuntu-latest
steps:
- id: checkout
uses: actions/checkout@master
- id: validate
uses: kubeshop/monokle-action@v0.2.0
with:
path: kubernetes/manifests

(Don’t forget to commit the configuration file to your repo so the GitHub action can use it…)

See more examples at https://github.com/marketplace/actions/monokle-validation#usage

Once executed, GitHub will show the outcome in the PR:‍

Going to the details of a failed check will show

‍Creating and Sharing Custom Validators

One of the more powerful aspects of the Monokle-CLI is the possibility to easily create, debug and share custom validators using typescript as the programming language. The process for this is straightforward:

  1. Bootstrap your own validator using the provided scaffolding provided by the create-monokle-plugin library
  2. Implement the validator in typescript, optionally using automatically generated types for target K8s resource kinds
  3. Optionally debug your validator in real-time using Monokle Cloud
  4. Publish the validator to the community-plugins repository (if you want to share)
  5. Use it using the configuration approach described above (Monokle CLI automatically has access to all plugins in the community repository)

A sample validator

Just to give you a taste of how easy it is to create a custom validator, here is a very simple example that ensures that each resource has at least one annotation:

export const noEmptyAnnotations = defineRule({
id: 1,
description: "Require annotations as metadata.",
help: "Add any annotation to the Kubernetes resource.",
validate({ resources }, { report }) {
resources.forEach((resource) => {
const annotations = Object.entries(resource.metadata?.annotations ?? {});
const hasAnnotations = annotations.length > 2;

if (!hasAnnotations) {
report(resource, { path: "metadata.annotations" });
}
});
},
});

This is taken from the corresponding [community plugin on GitHub]

Violating this rule results in:

And here you can see it in action in Monokle Cloud (more on that below…)

Integrating with Monokle Cloud

Monokle Cloud is a free browser-based tool for exploring, previewing and validating Kubernetes resources in public GitHub Repositories. For validation, it uses the same underlying library as the monokle-cli, allowing you to visually discover validation errors in your manifests without having to install any tools or run any commands. For example, navigating to one of the resources in the above repository shows the following:

‍A validation panel on the left allows you to enable/disable any validation just as you would in the configuration file described earlier immediately showing the update of error information in your manifests:

Real-time debugging Custom Validators

Monokle Cloud has one more trick up its sleeve in regards to custom validators — it can connect to the local development of your validator plugin and allow you to debug it in real-time — while you code it.

Provided you’ve scaffolded your plugin using our create-monokle-plugin toolkit — just run the following command

npm run dev

in your plugin folder — which will start a local server that you can connect to to Monokle Cloud in the validation panel:

‍What about Monokle Desktop?

Monokle Desktop currently performs validations with code that was used to extract the monokle validation library, but unfortunately hasn’t transitioned to use the actual library itself — this will be fixed in the next major release giving the same level of validation flexibility consistently across all tools in the Monokle ecosystem.

Give it a try

That’s it — hopefully you’re intrigued enough to try it out, either as your initial attempt at resource validation or as a complement to your existing tooling, and let us know what you think on our Discord Server.

Happy YAMLing…!‍

Originally published at https://monokle.io.

--

--