<p>OpenShift (and probably k8s, too) updates a deployment's existing environment variables and creates new ones when they were changed in the respective <code>DeploymentConfig</code> in a template file before applying it.</p>

<p>Is there a way to remove already existing environment variables if they are no longer specified in a template when you run <code>oc apply</code>?</p>

Christian
<p>There is a way to achieve what you need and for that you need to <a href="https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/" rel="nofollow noreferrer">patch</a> your objects. You need to use the patch type <code>merge-patch+json</code> and as a patch you need to supply a complete/desired list of env vars.</p>
<p>As an example lets consider this deployment:</p>
<pre><code>apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: mydeployment
  labels: 
    app: sample
spec: 
  replicas: 2 
  selector: 
    matchLabels:
      app: sample 
  template: 
    metadata:
      labels: 
        app: sample
    spec:
      containers:
      - name: envar-demo-container
        image: gcr.io/google-samples/node-hello:1.0    
        env:
        - name: VAR1
          value: &quot;Hello, I'm VAR1&quot;
        - name: VAR2
          value: &quot;Hey, VAR2 here. Don't kill me!&quot;      
</code></pre>
<pre><code>$ kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
mydeployment-db84d9bcc-jg8cb   1/1     Running   0          28s
mydeployment-db84d9bcc-mnf4s   1/1     Running   0          28s
</code></pre>
<pre><code>$ kubectl exec -ti mydeployment-db84d9bcc-jg8cb -- env | grep VAR
VAR1=Hello, I'm VAR1
VAR2=Hey, VAR2 here. Don't kill me!
</code></pre>
<p>Now, to remove VAR2 we have to export our yaml deployment:</p>
<pre><code>$ kubectl get deployments mydeployment -o yaml --export &gt; patch-file.yaml
</code></pre>
<p>Edit this file and remove VAR2 entry:</p>
<pre><code>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: sample
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: sample
    spec:
      containers:
      - env:
        - name: VAR1
          value: Hello, I'm VAR1
        image: gcr.io/google-samples/node-hello:1.0
        imagePullPolicy: IfNotPresent
        name: patch-demo-ctr
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status: {}
</code></pre>
<p>Now we need to patch it with the following command:</p>
<pre><code>$ kubectl patch deployments mydeployment --type merge --patch &quot;$(cat patch-file.yaml)&quot;
deployment.extensions/mydeployment patched
</code></pre>
<p>Great, If we check our pods we can see that we have 2 new pods and the old ones are being terminated:</p>
<pre><code>$ kubectl get pods
NAME                           READY   STATUS        RESTARTS   AGE
mydeployment-8484d6887-dvdnc   1/1     Running       0          5s
mydeployment-8484d6887-xzkhb   1/1     Running       0          3s
mydeployment-db84d9bcc-jg8cb   1/1     Terminating   0          5m33s
mydeployment-db84d9bcc-mnf4s   1/1     Terminating   0          5m33s
</code></pre>
<p>Now, if we check the new pods, we can see they have only VAR1:</p>
<pre><code>$ kubectl exec -ti mydeployment-8484d6887-dvdnc -- env | grep VAR
VAR1=Hello, I'm VAR1
</code></pre>
