17

So I am trying to build a helm chart.

in my templates file I've got a file like:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-map
data:
{{ Do something here to load up a set of files | indent 2 }}

I have another directory in my chart: configmaps where a set of json files, that themselves will have templated variables in them:

a.json
b.json
c.json

Ultimately I'd like to be sure in my chart I can reference:

volumes:
   - name: config-a
     configMap:
       name: config-map
       items:
       - key: a.json
         path: a.json
Nathan Feger
  • 19,122
  • 11
  • 62
  • 71
  • As I understood, you just need to create multiple ConfigMap templates, and then you can reference them in a pod templates. See an example here: https://github.com/kubernetes/charts/blob/master/stable/datadog/values.yaml#L121 and https://github.com/kubernetes/charts/blob/master/stable/datadog/templates/checksd-configmap.yaml – hypnoglow Dec 06 '17 at 16:15

3 Answers3

18

I had same problem for a few weeks ago with adding files and templates directly to container.

Look for the sample syntax:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configmap-{{ .Release.Name }}
  namespace: {{ .Release.Namespace }}
  labels:
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
data:
  nginx_conf: {{ tpl (.Files.Get "files/nginx.conf") . | quote }}
  ssl_conf: {{ tpl (.Files.Get "files/ssl.conf") . | quote }}
  dhparam_pem: {{ .Files.Get "files/dhparam.pem" | quote }}
  fastcgi_conf: {{ .Files.Get "files/fastcgi.conf" | quote }}
  mime_types: {{ .Files.Get "files/mime.types" | quote }}
  proxy_params_conf: {{ .Files.Get "files/proxy_params.conf" | quote }}

Second step is to reference it from deployment:

  volumes:
  - name: {{ $.Release.Name }}-configmap-volume
    configMap:
      name:nginx-configmap-{{ $.Release.Name }}
      items:
        - key: dhparam_pem
          path: dhparam.pem
        - key: fastcgi_conf
          path: fastcgi.conf
        - key: mime_types
          path: mime.types
        - key: nginx_conf
          path: nginx.conf
        - key: proxy_params_conf
          path: proxy_params.conf
        - key: ssl_conf
          path: ssl.conf 

It's actual for now. Here you can find 2 types of importing:

  • regular files without templating
  • configuration files with dynamic variables inside

Please do not forget to read official docs: https://helm.sh/docs/chart_template_guide/accessing_files/

Good luck!

jpbochi
  • 4,366
  • 3
  • 34
  • 43
  • can u pls tell me corresponding Dockerfile, I assume nginx.conf file has been put into files dir (ie files/nginx.conf in data) by Dockerfile's driective. – user1731045 Jun 12 '21 at 11:58
  • how did you reference to them in env? I did the same thing and the files are not loaded into the environment variable. https://stackoverflow.com/questions/72352655/multiple-configmap-files-in-helm – szend May 24 '22 at 06:55
4

include all files from directory config-dir/, with {{ range ..:

my-configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  {{- $files := .Files }}
  {{- range $key, $value := .Files }}
  {{- if hasPrefix "config-dir/" $key }} {{/* only when in config-dir/ */}}
  {{ $key | trimPrefix "config-dir/" }}: {{ $files.Get $key | quote }} {{/* adapt $key as desired */}}
  {{- end }}
  {{- end }}

my-deployment.yaml

apiVersion: apps/v1
kind: Deployment
...
spec:
  template:
    ...
    spec:
      containers:
        - name: my-pod-container
          ...
          volumeMounts:
            - name: my-volume
              mountPath: /config
              readOnly: true # is RO anyway for configMap
      volumes:
        - name: my-volume
          configMap:
            name: my-configmap
            # defaultMode: 0555 # mode rx for all
simohe
  • 613
  • 7
  • 20
0

I assume that a.json,b.json,c.json etc. is a defined list and you know all the contents (apart from the bits that you want to set as values through templated variables). I'm also assuming you only want to expose parts of the content of the files to users and not to let the user configure the whole file content. (But if I'm assuming wrong and you do want to let users set the whole file content then the suggestion from @hypnoglow of following the datadog chart seems to me a good one.) If so I'd suggest the simplest way to do it is to do:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-map
data:
  a.json:
  # content of a.json in here, including any templated stuff with {{ }}
  b.json:
  # content of b.json in here, including any templated stuff with {{ }}
  c.json:
  # content of c.json in here, including any templated stuff with {{ }}

I guess you'd like to mount then to the same directory. It would be tempting for cleanliness to use different configmaps but that would then be a problem for mounting to the same directory. It would also be nice to be able to load the files independently using .Files.Glob to be able to reference the files without having to put the whole content in the configmap but I don't think you can do that and still use templated variables in them... However, you can do it with Files.Get to read the file content as a string and the pass that into tpl to put it through the templating engine as @Oleg Mykolaichenko suggests in https://stackoverflow.com/a/52009992/9705485. I suggest everyone votes for his answer as it is the better solution. I'm only leaving my answer here because it explains why his suggestion is so good and some people may prefer the less abstract approach.

Ryan Dawson
  • 11,832
  • 5
  • 38
  • 61
  • Since your files are json an alternative option is to put the config content in the values.yaml and translate it to json with the toJson function - https://stackoverflow.com/questions/52839920/get-array-of-strings-from-helm-config/52840704#52840704 – Ryan Dawson Nov 28 '18 at 10:10