Using Files as ConfigMaps in Kubernetes
The canonical example for ConfigMaps in K8S looks something like this
apiVersion: v1kind: ConfigMapmetadata:name: special-confignamespace: defaultdata:SPECIAL_LEVEL: verySPECIAL_TYPE: charm
Personally, I have some issues with this:-
- When a developer manages the properties, I don't want the dev to accidentally mess with the other metadata that exists in the file.
- It's YAML. YAML with its indentation based namespacing is super easy to get wrong.
- When you have a large number of properties, or multiple properties files, you have either multiple ConfigMaps or a really large ConfigMap YAML file.
Configuration changes based on environment, so you're probably using some form of templatization over the YAML. The following is an example in Helm
apiVersion: v1kind: ConfigMapmetadata:name: special-confignamespace: defaultdata:SPECIAL_LEVEL: { { .Values.special_level } }SPECIAL_TYPE: { { .Values.special_type } }
So my goals were to:-
- Have propeties files seperate from the ConfigMap definition itself.
- It should be templatized.
- It should not be YAML.
So this is my solution!
File directory structure:
application-charts||---config| |--- file.properties| |--- file2.properties|---templates| |--- configmap.yaml| |--- deployment.yaml| |--- ...|---values.production.yaml|---values.qa.yaml|--- ...
My ConfigMap.yaml looks like this
apiVersion: v1kind: ConfigMapmetadata:name: special-configdata: { { - (tpl (.Files.Glob "config/*").AsConfig . ) | nindent 2 } }
And my properties file looks like this
somePropertyThatIsConstant=HELLOsomePropertyThatChanges={{ .Values.some_property_that_changes }}
Explanation
.Files.Glob
is a helper that Helm provides to read directories inside the Helm chart folder structure, and .AsConfig
is a helper
that reads the files as configuration. We then pass those files to the tpl
function to replace the template strings in the files.
We pipe the result to nindent 2
to correctly indent it with 2 spaces.