Can I reference a previously-defined key-value pair in a ConfigMap?
I'm writing a deployment specification for an application which accepts its configuration from environment variables at startup. Some of the environment variables are derived from others. If I were setting them up as file to be sourced at application startup, I would simply do:
[me@myserver ~]$ cat ./myenv.sh
export FOO=foo
export BAR=bar
export FOOBAR=$FOO$BAR
[me@myserver ~]$ . ./myenv.sh
[me@myserver ~]$ printenv FOOBAR
foobar
However, the analagous way to do this in a ConfigMap by referencing previously-defined key-value pairs doesn't work (see sample ConfigMap and Pod, below). Here are the results:
[me@myserver ~]$ kubectl create -f my-app-config.yaml -f my-app-pod.yaml
configmap "my-app" created
pod "my-app" created
[me@myserver ~]$ kubectl exec -it my-app -- printenv | grep MY_CONFIGMAP
MY_CONFIGMAP_FOO=foo
MY_CONFIGMAP_FOOBAR=$(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)
MY_CONFIGMAP_BAR=bar
Hoped-for value of MY_CONFIGMAP_FOOBAR
is foobar
.
I attempted to cross-apply the following instructions under Use ConfigMap-defined environment variables in Pod commands from the documentation:
You can use ConfigMap-defined environment variables in the
command
section of the Pod specification using the$(VAR_NAME)
Kubernetes substitution syntax.
However, this obviously did not work, and I've been unable to find an answer in my research.
I suspect I already know the answer, but is there any way to accomplish this?
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app
data:
MY_CONFIGMAP_FOO: foo
MY_CONFIGMAP_BAR: bar
# Desired concatenation would be `foobar`
MY_CONFIGMAP_FOOBAR: $(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: my-app
image: alpine
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: my-app
command:
- /bin/sh
args:
- -c
- "while true; do sleep 3600; done"
You can achieve your expected result with help of this tool: envsubst.
Create the ConfigMap
following way,
envsubst < my-app-config.yaml | kubectl apply -f -
Now, all environment variables on your ConfigMap
will be replaced with resolved value.
The recommendation is to use kind: Deployment
Combining variables works fine in that config file. I haven't tried pods directly.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
replicas: 1
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: alpine
imagePullPolicy: IfNotPresent
env:
- name: MY_CONFIGMAP_FOOBAR
value: $(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)