<p>My Kubernetes deployment has an <code>initContainer</code> which fetches a token from a URL. My app container (3rd party) then needs that token as an environment variable.</p>
<p>A possible approach would be: the <code>initContainer</code> creates a Kubernetes Secret with the token value; the app container <a href="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables" rel="nofollow noreferrer">uses the secret as an environment variable</a> via <code>env[].valueFrom.secretKeyRef</code>.</p>
<p>Creating the Secret from the <code>initContainer</code> requires <a href="https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/#directly-accessing-the-rest-api" rel="nofollow noreferrer">accessing the Kubernetes API from a Pod</a> though, which tends to be a tad cumbersome. For example, <a href="https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/#directly-accessing-the-rest-api" rel="nofollow noreferrer">directly accessing the REST API</a> requires granting proper permissions to the pod's service account; otherwise, creating the secret will fail with</p>
<pre><code>secrets is forbidden: User \&quot;system:serviceaccount:default:default\&quot; 
cannot create resource \&quot;secrets\&quot; in API group \&quot;\&quot; in the namespace \&quot;default\&quot;
</code></pre>
<p>So I was wondering, isn't there any way to just write the token to a file on an <code>emptyDir</code> volume...something like this:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  labels:
    app: my-app
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      initContainers:
        - name: fetch-auth-token
          image: curlimages/curl
          command:
            - /bin/sh
          args:
            - -c
            - |
              echo &quot;Fetching token...&quot;
              url=https://gist.githubusercontent.com/MaxHorstmann/a99823d5aff66fe2ad4e7a4e2a2ee96b/raw/662c19aa96695e52384337bdbd761056bb324e72/token
              curl $url &gt; /auth-token/token
          volumeMounts:
            - mountPath: /auth-token
              name: auth-token
...
      volumes:
        - name: auth-token
          emptyDir: {}
</code></pre>
<p>... and then somehow use that file to populate an environment variable in the app container, similar to <code>env[].valueFrom.secretKeyRef</code>, along the lines of:</p>
<pre><code>      containers:
        - name: my-actual-app
          image: thirdpartyappimage
          env:
            - name: token
              valueFrom:
                fileRef:
                  path: /auth-token/token
            # ^^^^ this does not exist
          volumeMounts:
            - mountPath: /auth-token
              name: auth-token
</code></pre>
<p>Unfortunately, there's no <code>env[].valueFrom.fileRef</code>.</p>
<p>I considered overwriting the app container's <code>command</code> with a shell script which loads the environment variable from the file before launching the main command; however, the container image doesn't even contain a shell.</p>
<p>Is there any way to set the environment variable in the app container from a file?</p>

Max
<blockquote>
<p>Creating the Secret from the initContainer requires accessing the Kubernetes API from a Pod though, which tends to be a tad cumbersome...</p>
</blockquote>
<p>It's not actually all that bad; you only need to add a ServiceAccount, Role, and RoleBinding to your deployment manifests.</p>
<p>The ServiceAccount manifest is minimal, and you only need it if you don't want to grant permissions to the <code>default</code> service account in your namespace:</p>
<pre><code>apiVersion: v1
kind: ServiceAccount
metadata:
  name: secretmaker
</code></pre>
<p>Then your Role grants access to secrets (we need <code>create</code> and <code>delete</code> permissions, and having <code>get</code> and <code>list</code> is handy for debugging):</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app: env-example
  name: secretmaker
rules:
- apiGroups:
  - &quot;&quot;
  resources:
  - secrets
  verbs:
  - create
  - get
  - delete
  - list
</code></pre>
<p>A RoleBinding connects the ServiceAccount to the Role:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app: env-example
  name: secretmaker
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secretmaker
subjects:
- kind: ServiceAccount
  name: secretmaker
  namespace: default
</code></pre>
<p>And with those permissions in place, the Deployment is relatively simple:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: env-example
  name: env-example
  namespace: env-example
spec:
  selector:
    matchLabels:
      app: env-example
  template:
    metadata:
      labels:
        app: env-example
    spec:
      serviceAccountName: secretmaker
      initContainers:
      - command:
        - /bin/sh
        - -c
        - |
          echo &quot;Fetching token...&quot;
          url=https://gist.githubusercontent.com/MaxHorstmann/a99823d5aff66fe2ad4e7a4e2a2ee96b/raw/662c19aa96695e52384337bdbd761056bb324e72/token
          curl $url -o /tmp/authtoken
          kubectl delete secret authtoken &gt; /dev/null 2&gt;&amp;1
          kubectl create secret generic authtoken --from-file=AUTH_TOKEN=/tmp/authtoken
        image: docker.io/alpine/k8s:1.25.6
        name: create-auth-token
      containers:
      - name: my-actual-app
        image: docker.io/alpine/k8s:1.25.6
        command:
        - sleep
        - inf
        envFrom:
        - secretRef:
            name: authtoken
</code></pre>
<p>The application container here is a no-op that runs <code>sleep inf</code>; that gives you the opportunity to inspect the environment by running:</p>
<pre><code>kubectl exec -it deployment/env-example -- env
</code></pre>
<p>Look for the <code>AUTH_TOKEN</code> variable created by our <code>initContainer</code>.</p>
<hr />
<p>All the manifests mentioned here can be found in <a href="https://github.com/larsks/so-example-75265056-createsecret" rel="nofollow noreferrer">this repository</a>.</p>
