How can I generate a configmap from a directory of files that need to be templated?

9/10/2019

I can generate the ConfigMap from the directory but they are not translating the template directives or values. Below is an example of the Release.Namespace template directive not being output in the ConfigMap.

.
|____Chart.yaml
|____charts
|____.helmignore
|____templates
| |____my-scripts.yaml
|____values.yaml
|____test-files
  |____test1.txt
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: {{ .Release.Namespace }}
data:
  test.txt: |-
{{ .Files.Get "test-files/test1.txt" | indent 4}}
# test-files/test1.txt
test file
{{ .Release.Namespace }}

When I run helm install . --dry-run --debug --namespace this-should-print here's what I'm getting vs what I'm expecting:

Actual:

---
# Source: test/templates/my-scripts.yaml
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: test
data:
  test.txt: |-
    # test-files/test1.txt
    test file
    {{ .Release.Namespace }}

Expected:

---
# Source: test/templates/my-scripts.yaml
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: test
data:
  test.txt: |-
    # test-files/test1.txt
    test file
    this-should-print

Alternatively, I would be interested in every file in a specified directory being output in the format like:

<filename>: |-
  <content>
-- James
kubernetes
kubernetes-helm

2 Answers

9/11/2019

.Files.Get will take the raw contents of those files and dump it into your resulting YAMLs, if you want those file contents to be subject to Helm template rendering themselves, this approach won't work. You can instead create named templates and then include them within other templates.

Directory Structure: tree

.
├── Chart.yaml
├── templates
│   ├── _test1.tpl
│   └── my-scripts.yaml
└── values.yaml

Template: cat templates/my-scripts.yaml

---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: {{ .Release.Namespace }}
data:
  test.txt: |-
{{- include "mychart.test1" . | indent 4 }}

Helper: cat templates/_test1.tpl

{{- define "mychart.test1" }}
test file
{{ .Release.Namespace }}
{{- end }}

Result: helm template . --namespace this-should-print

---
# Source: helm/templates/my-scripts.yaml
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: this-should-print
data:
  test.txt: |-
    test file
    this-should-print
-- Amit Kumar Gupta
Source: StackOverflow

9/11/2019

I've found a way of doing it using the tpl function:

---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: {{ .Release.Namespace }}
data:
  test.txt: |-
{{ tpl ( .Files.Get "test-files/test1.txt" ) . | indent 4 }}

The new output is exactly as expected:

# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: this-should-print
data:
  test.txt: |-
    # test-files/test1.txt
    test file
    this-should-print

And for bonus points, getting all files from a directory without having to update this list within the config map:

---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-scripts
  namespace: {{ .Release.Namespace }}
data:
{{ tpl (.Files.Glob "groovy-scripts/*").AsConfig . | indent 4 }}
-- James
Source: StackOverflow