<p>I'm laying the foundation for a new project where we will have an application running on Google Kubernetes Engine with multiple environments (development, staging, production). Each environment is its own GC Project.</p>

<p>I'm writing some manifest files and I'd like to abstract out any environment specific values so it can be re-used depending what environment (project) were updating/deploying to.</p>

<p>I have created values in Kubernetes Secrets, and turning those into ENV's is straight forward (see <code>DATABASE_URL</code>). However, if I wanted to use a variable for the value of the container image: <code>gcr.io/my-app-production-123:latest</code>, how would I pass in the value from a secret?</p>

<p>Is this the correct approach to abstracting environment specific values from manifest files? Thank you!</p>

<pre><code>apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
spec:
  completions: 1
  template:
    metadata:
      name: db-migrate
    spec:
      restartPolicy: Never
      containers:
      - name: db-migrate
        # how can I reference secret/env for the value of image:?
        image: gcr.io/my-app-production-242920:latest
        args: ["bundle", "exec", "rake", "db:create", "db:migrate"]
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: DATABASE_URL
</code></pre>

hummmingbear
<p>You probably need to use a higher-level tool to inject variables like this.  The one I'm familiar with is <a href="https://helm.sh" rel="nofollow noreferrer">Helm</a> but there are other tools that let you inject parameters into the YAML files as well.</p>

<p>You can't use secrets the way you're describing.  The only things you can do with secrets (or config maps, they're very similar) are to <a href="https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#create-a-pod-that-has-access-to-the-secret-data-through-a-volume" rel="nofollow noreferrer">mount them as files</a> or use them to <a href="https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data" rel="nofollow noreferrer">set environment variables</a>.  You can, to a limited extent, <a href="https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#using-environment-variables-inside-of-your-config" rel="nofollow noreferrer">use environment variables to define other parts of the config</a>; but if you look at <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#container-v1-core" rel="nofollow noreferrer">the API reference for containers</a> the places where the <code>$(VARIABLE)</code> syntax is allowed are specifically called out, and it is only allowed for <code>args:</code>, <code>command:</code>, and <code>env:</code>.</p>

<p>In Helm you can use Go's templating syntax in your YAML files, and so could write</p>

<pre><code>image: gcr.io/my-app-production:{{ .Values.tag }}
</code></pre>

<p>and then deploy the service with something like</p>

<pre><code>helm install ./my-app --set tag=242920
</code></pre>

<p>but I'm pretty sure there's not a way to parameterize pods (or deployments or statefulsets or ...) in plain unadorned Kubernetes.</p>
