How to create configMap with .env with Kustomize

12/23/2021

I've a NextJS app which needs a .env file mounted. I usually do this with providing a configMap:

kind: ConfigMap
apiVersion: v1
metadata:
  name: frontend-configmap
  namespace: default
data:
  .env: |-
    NEXT_PUBLIC_API_URL=http://my.domain.com
    API_URL=http://my.domain.com

But how to do this with Kustomize?

I try it with envs, but how do I get the values inside?

configMapGenerator:
  - name: frontend-configmap
    envs:
      - .env

Thank you in advance

-- Jan
environment-variables
kubernetes
kustomize

1 Answer

12/24/2021

You need to have .env file created first. And ideally even creating configmaps should be based on the existing file (below are examples for kustomize and kubectl --from-file).

Then there are two options how to create a configmap:

  • create .env file with environment variables within (which is your example configmap)
  • create a configmap with environment variables from .env file (each variable is a separate key)

Test structure:

$ tree -a
.
├── .env
└── kustomization.yaml


$ cat .env # same as your test data

NEXT_PUBLIC_API_URL=http://my.domain.com
API_URL=http://my.domain.com

configmap with .env file with envvars inside:

kustomization.yaml with an additional option :

$ cat kustomization.yaml 

configMapGenerator:
  - name: frontend-configmap
    files: # using files here as we want to create a whole file
      - .env
generatorOptions:
  disableNameSuffixHash: true # use a static name

disableNameSuffixHash - disable appending a content hash suffix to the names of generated resources, see generator options.

And all left is to run it:

$ kustomize build .

apiVersion: v1
data:
  .env: | # you can see it's a file with context within
    NEXT_PUBLIC_API_URL=http://my.domain.com
    API_URL=http://my.domain.com
kind: ConfigMap
metadata:
  name: frontend-configmap

The same result can be achieved by running using --from-file option:

$ kubectl create cm test-configmap --from-file=.env --dry-run=client -o yaml

apiVersion: v1
data:
  .env: |
    NEXT_PUBLIC_API_URL=http://my.domain.com
    API_URL=http://my.domain.com
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: test-configmap

configmap with envvars as keys within:

$ cat kustomization.yaml 

configMapGenerator:
  - name: frontend-configmap
    envs: # now using envs to create a configmap with envvars as keys inside
      - .env
generatorOptions:
  disableNameSuffixHash: true # use a static name

Run it to see the output:

$ kustomize build .

apiVersion: v1
data: # you can see there's no file and keys are created directly
  API_URL: http://my.domain.com
  NEXT_PUBLIC_API_URL: http://my.domain.com
kind: ConfigMap
metadata:
  name: frontend-configmap

Same with kubectl and --from-env-file option:

$ kubectl create cm test-configmap --from-env-file=.env --dry-run=client -o yaml

apiVersion: v1
data:
  API_URL: http://my.domain.com
  NEXT_PUBLIC_API_URL: http://my.domain.com
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: test-configmap

More details:


Edit - use already existing configmap.yaml

If configmap already exists, then it's possible to reference to it from kustomization.yaml (as mentioned in comment, kustomize is a template engine and using it with this direct reference only without any transformations doesn't really make sense. Here is one of the examples of why you need to use kustomize).

$ tree
.
├── cm.yaml
└── kustomization.yaml

cm.yaml has exactly the same config from the question.

$ cat kustomization.yaml
 
resources:
- cm.yaml
namePrefix: test- # used namePrefix for demo purpose (you can omit it as well)

Building this and getting the same configmap with .env file inside:

$ kustomize build .

apiVersion: v1
data:
  .env: |-
    NEXT_PUBLIC_API_URL=http://my.domain.com
    API_URL=http://my.domain.com
kind: ConfigMap
metadata:
  name: test-frontend-configmap # name with prefix as it was setup for demo
  namespace: default
-- moonkotte
Source: StackOverflow