Environments
At this point, our configuration is already flexible and concise, but not really reusable. Let’s take a look at Tanka’s third buzzword as well: Environments.
These days, the same piece of software is usually deployed many times inside a
single organization. This could be dev
, testing
and prod
environments, but
also regions (europe
, us
, asia
) or individual customers (foo-corp
,
bar-gmbh
, baz-inc
).
Most of the application however is exactly the same across those environments …
usually only configuration, scaling or small details are different after all.
YAML (and thus kubectl
) provides us only one solution here: Duplicating the
directory, changing the details, maintaining both. But what if you have 32
environments? Correct! Then you have to maintain 32 directories of YAML. And we can all
imagine the nightmare of these files drifting apart from each other.
But again, Jsonnet can be the solution: By extracting the actual objects into a library, you can import them in as many environments as you need!
Creating a library
A library is nothing special, just a folder of .libsonnet
files somewhere in the import paths:
Path | Description |
---|---|
/lib | Custom, user-created libraries only for this project. |
/vendor | External libraries installed using Jsonnet-bundler |
So for our purpose /lib
fits best, as we are only creating it for our current
project. Let’s set one up:
For documentation purposes it is handy to have a separate file for parameters and used images:
Dev and Prod
So far we have only used the environments/default
environment. Let’s create some real ones:
All that’s left now is importing the library and configuring it. For dev
, the defaults defined in /lib/prom-grafana/config.libsonnet
should be sufficient, so we do not override anything:
For prod
however, it is a bad idea to rely on latest
for the images .. let’s
add some proper tags:
Patching
The above works well for libraries we control ourselves, but what when another
team wrote the library, it was installed using jb
from GitHub or you can’t
change it easily?
Here comes the already familiar +:
(or +::
) syntax into play. It allows to
partially override values of an object. Let’s say we wanted to add some labels to the Prometheus Deployment
, but our _config
params don’t allow us to. We can still do this in our main.jsonnet
:
By using the +:
operator all the time and only foo: "bar"
uses “:
”, we only
override the value of "foo"
, while leaving the rest of the object like it was.
Let’s check it worked: