I work a lot with Kustomize and I love Neovim. So why not write a plugin for some tasks for that I usually switch to a shell. Jump to the use cases to check out what this plugin can do!
- Neovim >= 0.9
kustomize
in your PATH to build manifests- kubeconform in your PATH to validate manifests
- kubent in your PATH to check for deprecations
- plenary.nvim
- nvim-treesitter and
yaml
parser - (optionally) LuaSnip for snippets support (default is disabled)
With Lazy.nvim:
{
"allaman/kustomize.nvim",
requires = "nvim-lua/plenary.nvim",
dependencies = "nvim-lua/plenary.nvim"
ft = "yaml",
opts = {}
}
Run :checkhealth kustomize
for a health check.
Mode | Mapping | Action | Command |
---|---|---|---|
n | <leader>kb | Kustomize build | :KustomizeBuild |
n | <leader>kk | List kinds | :KustomizeListKinds |
n | <leader>kp | Print resources | :KustomizePrintResources |
n | <leader>kl | List 'resources' | :KustomizeListResources |
n | <leader>kv | Validate file | :KustomizeValidate |
n | <leader>kd | Check API deprecations | :KustomizeDeprecations |
n | Run custom commands | :KustomizeRun <command> |
You can define your own keybindings after setting opts.enable_key_mappings = false
:
use({
"allaman/kustomize.nvim",
requires = "nvim-lua/plenary.nvim",
ft = "yaml",
opts = { enable_key_mappings = false },
config = function(opts)
require('kustomize').setup({opts})
-- adjust to your needs if not using the default key mappings
vim.api.nvim_set_keymap("n", "<leader>kb", "<cmd>KustomizeBuild<cr>", { desc = "Build Kustomize" })
vim.api.nvim_set_keymap("n", "<leader>kk", "<cmd>KustomizeListKinds<cr>", { desc = "List Kubernetes Kinds" })
-- ...
end,
})
This is the default configuration that can be overwritten, also in parts, by you.
{
enable_key_mappings = true,
enable_lua_snip = false,
build = { additional_args = {} },
kinds = { show_filepath = true, show_line = true, exclude_pattern = {} },
-- built-in commands
run = {
validate = {
cmd = "kubeconform",
args = {
"--strict",
"--ignore-missing-schemas",
"-schema-location",
"default",
"-schema-location",
"https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json",
},
},
deprecations = {
cmd = "kubent",
args = { "-t", "1.26", "-c=false", "--helm3=false", "-l=error", "-e", "-f" },
},
},
}
With Lazy.nvim for instance:
opts = { enable_lua_snip = true },
If enabled, kustomize.nvim includes some useful snippets for LuaSnip. All snippets start with kust
.
This command will run kustomize build .
in the current buffer's directory. The generated YAML will be printed to a new buffer. The new buffer can be closed by just typing q
.
This allows me to quickly inspect the YAML that Kustomize generates (and ultimately is applied to the cluster). In addition, I get fast feedback on any errors in my YAML sources.
You can add additional arguments to the build call via config file:
build = {
additional_args = {"--enable-helm", "--load-restrictor=LoadRestrictionsNone"}
},
You can also dynamically overwrite the values of your config file with
:KustomizeBuild --enable-helm --load-restrictor=LoadRestrictionsNone
Sometimes, I just want to roughly check the YAMLs generated by Kustomize. A good hint is to check the kind:
key of the generated YAML manifests. This command will parse all kind:
keys in the current buffer with the help of tree-sitter and prints their values to a loclist allowing you to easily jump around all resources. You could use it on any YAML file with multiple resources, for instance generated by Build manifests. Only Resources with metadata.name
are recognized, e.g. Kustomization
resources are not detected.
The output consists of <buffer-name> |<line-nr>| <kind> <name> <namespace>
. Cluster-wide resources omit the namespace value. You can hide the buffer name and line number by adding the following snippet to the opts table:
kinds = {
show_filepath = false,
show_line = false,
},
You can exclude certain resources from the results via:
kinds = {
exclude_pattern = { "CronJob", "ServiceAccount" }
},
You can also dynamically overwrite the values of your config file with
:KustomizeListKinds show_line=false show_filepath=false exclude_pattern=Namespace,Ingress
If Telescope.nvim is installed, you can toggle Telescope loclist
with <leader>kt
(if default mappings are enabled).
In a kustomiation.yaml you list your YAMLs that should be included by Kustomize for the build of the final manifests like so:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service1/
- grafana-dashboard.yaml
- ../../base/namespace.yaml
In order to quickly check/edit those included YAMLs this command will go through all items in resources:
and populate a loclist with them.
When writing a new deployment I usually split the resources into files according to their type, for instance deployment.yaml
, cm.yaml
, or sa.yaml
. When writing my kustomization.yaml
I must add all resource files which does this command for me.
kubeconform is a Kubernetes manifests validator that can detect a misconfiguration before you apply your manifests to your cluster. This command runs kubeconform --strict --ignore-missing-schemas
on the current buffer. The buffer's content may be a file on disk or content not (yet) saved, e.g. the output of Build manifests.
You can overwrite the default args like so
run = {
validate = {
args = { "--strict" },
},
}
kubent is a tool to search for deprecated Kubernetes APIs. This plugin utilizes the plugin to check the manifests in the current buffer for deprecated Kubernetes APIs. The buffer's content may be a file on disk or content not (yet) saved, e.g. the output of Build manifests.
You can overwrite the default args like so
run = {
deprecations = {
args = { "-t", "1.30", "-l=error", "-e", "-f" },
}
You can define and run arbitrary commands on yaml files, for instance:
run = {
trivy = {
cmd = "trivy",
args = { "-q", "fs" },
timeout = 10000, -- in ms
},
deprecations29 = {
cmd = "kubent",
args = { "-t", "1.29", "-c=false", "--helm3=false", "-l=error", "-e", "-f" },
-- the default timeout is 5000 when not specified
},
deprecations30 = {
cmd = "kubent",
args = { "-t", "1.29", "-c=false", "--helm3=false", "-l=error", "-e", "-f" },
},
},
Keep in mind, that the last argument of the command must accept a file.
Then you can run :KustomizeRun trivy
to run the specified command. Auto-completion is supported!