It’s been a year since I did the ‘Hello World’ with Jsonnet and Tanka, then I made a simple side-loader container to install Tanka as a plugin to ArgoCD and finally deployed an httpbin container with ArgoCD + Tanka + Jsonnet. However since Jsonnet wasn’t used in my work, those things were shelved afterwards.
Recently I got a new gig where Jsonnet was heavily used for infrastructure as code and configuration as code purposes. So I think it’s a no-brainer to practise Jsonnet again, with my blog as the playground.
The Jsonnet Migration
Here are some tips on how to translate existing YAML/Kustomize manifests to Jsonnet/Tanka combo. To prepare a project for Jsonnet, try tk init in an empty directory like I did in my ‘Hello World’ experiment.
First of all, and the best of all, Jsonnet is a super set of JSON. This means if I put a raw JSON in a Jsonnet file, it should just work. So if I wasn’t sure how to handle a certain type of resource, I’ll just keep it as it is in JSON, eg.
{
namespace:
{
"apiVersion": "v1",
"kind": "Namespace",
...
}
}If it’s a large JSON block, it can even be imported via import function. By this way I can hide some ugly raw JSON such as SealedSecrets away.
{
sealed_secret: import 'sealed-secrets.json'
...
}ConfigMap was managed by kustomize and it’s relatively straightforward to use importstr function to import them.
(import 'k.libsonnet') + {
local cm = $.core.v1.configMap,
nginx_configmap:
cm.new('nginx-config', { 'nginx.conf': importstr 'conf/nginx.conf'}),
...
} To use the super k8s-libsonnet library, The document is quite handy. For instance, according to the namespace object, I can immediately translate the above JSON for a namespace into Jsonnet.
(import 'k.libsonnet') + {
local namespace = $.core.v1.namespace,
namespace: namespace.new('wordpress') +
namespace.mixin.metadata.withLabels({ "istio.io/rev": 'beta' }),
...
}Surprisingly almost all the time a service has same labels, eg. app=wordpress for selectors as the deploy which the service linked to. This is easily done using references started with a $, which is the root element.
(import 'k.libsonnet') + {
local deploy = $.apps.v1.deployment,
local svc = $.core.v1.service,
...
deploy: { ... },
service:
svc.new($.deploy.metadata.name, $.deploy.spec.selector.matchLabels, [
{ name: 'http-wp', port: 8080, targetPort: 8080 }
]),So line by line here’s my Jsonnet powered manifest for my blog, you can compare it with the original kustomize version, too. The Jsonnet version is rather plain and without a lot abstractions for now.
🙂
