<p>I have use-case to append pod name into &quot;<strong>jdbc_db_url</strong>&quot; property. which locate in &quot;<strong>common-configmap.config</strong>&quot; file.  In order to achieve I have followed the below steps, but unfortunately unable to make it.</p>
<p><strong>Step 1:</strong>
<strong>common-configmap.config</strong></p>
<pre><code># Database Properties
jdbc_auto_commit=false

jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}
</code></pre>
<p><strong>Step 2:</strong>
Using below command deploying configmap into cluster</p>
<pre><code>kubectl create configmap common-configmap --from-env-file /app/conf/common-configmap.config -n default
</code></pre>
<p><strong>Step 3:</strong>
Using below manifest files created the &quot;myapp&quot; container and service</p>
<p>Deployment Manifest file:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: &quot;1&quot;
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  generation: 1
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: master
      app.kubernetes.io/name: myapp
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: &quot;true&quot;
      labels:
        app.kubernetes.io/instance: master
        app.kubernetes.io/name: myapp
    spec:
      containers:
      - env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: myapp-configmap
        - configMapRef:
            name: common-configmap
        image: docker.com/myapp:4.0.0
        imagePullPolicy: Always
        name: myapp
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
</code></pre>
<p>Service Manifest file:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  ports:
 - name: http
    port: 8080
    protocol: TCP
    targetPort: http
  selector:
    app.kubernetes.io/instance: master
    app.kubernetes.io/name: myapp
  sessionAffinity: None
  type: ClusterIP
</code></pre>
<p>verifying the result I have getting into a shell running container and print the environment variables:</p>
<pre><code>kubectl exec --stdin --tty myapp-d5db776b9-h25q5 -c myapp -- /bin/sh
</code></pre>
<p><strong>Actual Result:</strong></p>
<pre><code># printenv

jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}
</code></pre>
<p><strong>Expected Result:</strong></p>
<pre><code>jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=myapp-d5db776b9-h25q5
</code></pre>
<ul>
<li><p>How do I substitute the environment variable in config-map while
deploying/container runtime?  or Is there any other way how to
pass/substitute the <strong>pod_name</strong> in the <strong>JDBC_URL</strong></p>
</li>
<li><p>May i know, What did I do wrong in this case?</p>
</li>
</ul>
<p>Thank you in advance for the help.</p>

<p>You can do that with an init-container which has a shared volume of type <code>emptyDir</code> between it and your main container.</p>
<p>First, edit your deployment to add an <code>emptyDir</code> volume and an init container, and mount the volume to both containers:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: &quot;1&quot;
    meta.helm.sh/release-name: master
    meta.helm.sh/release-namespace: default
  generation: 1
  labels:
    app.kubernetes.io/instance: master
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: myapp
    app.kubernetes.io/version: 4.0.0
    helm.sh/chart: myapp-4.0.0
  name: myapp
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: master
      app.kubernetes.io/name: myapp
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: &quot;true&quot;
      labels:
        app.kubernetes.io/instance: master
        app.kubernetes.io/name: myapp
    spec:
      volumes: # emptyDir volume for the entire pod
        - name: config-volume
          emptyDir: {}
      initContainers: # an init container that will compile the env var with the pod name
      - name: config-compiler
        image: bash
        volumeMounts:
        - name: config-compiler
          mountPath: /configs
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: common-configmap
        command: 
        - bash
        - -c
        - 'echo $jdbc_db_url | sed &quot;s/POD_NAME/${POD_NAME}/&quot; &gt; /configs/compiled.env'
      containers:
      - volumeMounts:
        - name: config-compiler
          mountPath: /configs
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        envFrom:
        - configMapRef:
            name: myapp-configmap
        - configMapRef:
            name: common-configmap
        image: docker.com/myapp:4.0.0
        imagePullPolicy: Always
        name: myapp
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
</code></pre>
<p>Then, you'll need to make sure that your actual pod is reading the env vars file - you can either do that by editing your entrypoint script to add a line like so:</p>
<pre><code>source /configs/compiled.env
</code></pre>
<p>or edit the the command of your pod to something like so:</p>
<pre class="lang-yaml prettyprint-override"><code>command: [ 'source', '/configs/compiled.env;', 'previous-command' ]
</code></pre>
<p>Both of the above are a bit hack-ish - so what I recommend doing, is to see what config files your app reads by default, and to match your compiling script to those.</p>
<p>For example, if your app reads from <code>/etc/myapp/confs.d/files.env</code> - mount your empty dir to <code>/etc/myapp/confs.d</code> and have the init container write to <code>files.env</code>, and do so in the format your app expects (e.g. if it's an ini file instead of an env file, compile it so it will match that format)</p>
<p>And obviously there are better ways to compile a config file then with <code>sed</code> - but it's an option if you want (and can afford) to keep things short</p>
