Yaml language server: Meaningful feedback for yaml-encoded values

Emil Snorre Alnæs

Writing the previous post on indentguides it became clear that indentguides fix accidental scope errors, on the level of alerting you if you accidentally put something on the wrong side of a curly brace. The more interesting problem in yaml-encoded configuration is actual semantic checking, same as if you give a bad argument to a function in your favorite programming language.

The Yaml language server is what we're looking for here. It's possible to set it up with a "kubernetes" check for kubernetes objects, but that also involves setting up a general path discovery rule, which seems a little annoying across machines and repos. So what we're going to look at here is the inline annotation. It's just a little comment:

---
# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.28.2-standalone-strict/namespace-v1.json
apiVersion: v1
kind: Namespace
metadata:
  name: hello-world
...

We're using yannh/kubernetes-json-schema here, which seems to be the successor to instrumenta/kubernetes-json-schema / kubernetesjsonschema.dev. You'd maybe think that kubernetes puts out the schemas themselves, but it's apparently left to the user to generate them. For CRDs you might be able to find something, but you might also wind up generating the schemas yourself with openapi2jsonschema.

If you have these locally available, or you have another json schema that you wrote for a helm chart, you can give a local path. Finding a good way to share a url to a schema file in a private repo is TODO for my part; the simple option seems to be open sourcing if not the chart, then at least the schema. In the locally available case it looks like

---
# yaml-language-server: $schema=../../etc
frobnicate: oh my  # should give an error
...

Setup will, again, depend on editor.

My impression is also that while yamlls will provide completion suggestions, it doesn't know where a key is supposed to go until after it's been placed. So having some guide to the permitted tree structure while creating a new yaml document might have to be another blog post, if someone knows about a good tool for that outside just reading the docs.

Other specs than json schema

For kubernetes CRDs it'd be nice if you could use the CRD directly. Unfortunately this doesn't seem to work. So unless Someone™ adds support for it, you're likely better off still just thinking of yaml as pretty-printed json (even though it definitely isn't) and sticking to jsonschema.

neovim

Assuming you have lsp setup and the yaml language server installed, it should Just Work. You can tweak the lsp config if you want, but there's no need to do so if you just want error messages. Enabling completion takes a little config:

require("lspconfig").yamlls.setup {
  settings = {
    yaml = {
      completion = true,
    },
  },
}

In any case, with yamlls working, you'll see something like this:

Neovim yamlls correction
yaml language server corrective feedback in neovim
Neovim yamlls suggestion
yaml language server suggestive feedback in neovim. For some reason the errors don't display in insert mode.

vscode

There's a marketplace entry for yaml language support.

jetbrains

idk, I couldn't find anything searching for "yamlls" jetbrains. Send a DM or PR if anyone knows.

emacs

I didn't even search for it, I'm just assuming someone else will do the work for me and send the solution so it can be included here.