Update 25.07.2021: As mentioned before, the vars option will be deprecated in favor of replacements.
Kustomize is a declarative configuration tool for Kubernetes. And unlike other tools like Helm, it's "template-free", in a simple put, it's like merging dictionaries (Python) or maps (Java).
A pure declarative style could be annoying sometimes! But actually, Kustomize has a feature called "vars" that allows you to cross-reference K8s objects, or in other words:
Vars are used to capture text from one resource's field and insert that text elsewhere - a reflection feature.
So I used this feature to unify vars, making it easier to group vars and also for better visibility. The idea is simple, using one or more ConfigMap as a source for vars. Let's have an example to make it more clear assuming that you already know Kustomize basics.
ToC
How?
Let's take the famous example on Kubernetes docs as a base for our example which is Deploying WordPress and MySQL with Persistent Volumes. In 3 steps, we will use ConfigMap as vars source in Kustomize.
Step 1 - Create ConfigMap
In the base dir of the component a new ConfigMap will be created it will have all vars for that component (visibility: by just looking at that file, component internals are more visible).
This ConfigMap could actually be filtered using a plugin, so it just works as a transient object and it's not be applied to K8s API.
# base/mysql/vars/configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: vars-mysql data: persistent-storage: /var/lib/mysql
Step 2 - Edit Kustomization file
Now we are going to add 3 things to the kustomization.yaml file, the ConfigMap that we just created, the var reference, and the actual var in
# base/mysql/kustomization.yaml resources: [...] - vars/configmap.yaml varReference: [...] - path: data kind: ConfigMap vars: [...] - name: MYSQL_PERSISTENT_STORAGE fieldref: fieldPath: data.persistent-storage objref: apiVersion: v1 kind: ConfigMap name: vars-mysql
Step 3 - Use the new Kustomize var
Now the new var MYSQL_PERSISTENT_STORAGE could be used like other Kustomize vars, and it's going to be replaced by Kustomize when applied. For example, let's use it in the StatefulSet resource.
# base/mysql/statefulset.yaml env: [...] - name: MYSQL_PERSISTENT_STORAGE value: $(MYSQL_PERSISTENT_STORAGE) volumeMounts: [...] - name: mysql-persistent-storage mountPath: $(MYSQL_PERSISTENT_STORAGE)
Why?
So let me tell you why this method is really helpful:
- In Kustomize base it gives more visibility, where anyone can know what configs are used in the component.
- In Kustomize overlay it gives clarity where "MYSQL_PERSISTENT_STORAGE" is more clear than just "/var/lib/mysql".
- In general it helps readability and avoid any confusion because in many cases the same value could represent different use. e.g. a value could be used in more than place for different contexts.
- It's easy to change any value at anytime.
- It's easy to introduce, there is not big change there.
Caveats
This method works pretty well, however, there are a couple of caveats you need to consider.
Mainly, the vars functionality is limited by design in Kustomize! The find & replace doesn't work everywhere and Kustomize supports predefined list of paths where the replacements are effective!
For the same reason, the issue #2052 - kustomize vars - enhance or replace? was created to discuss the future of the vars functionality in Kustomize. It's a long issue with a lot of details but it seems that everyone agrees that vars would be removed at a certain point and probably that will be soon!
That's why it's maybe a good idea to wait a bit till the new successor is there or find/implement a plugin to do the same to avoid migration later.
That's it, enjoy :-)