Templating external files in helm

1/23/2020

I want to use application.yaml file to be passed as a config map.

So I have written this.

 apiVersion: v1
 kind: ConfigMap
 metadata:
  name: conf
data:
{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}

my application.yaml is present in foo folder and contains a service name which I need it to be dynamically populated via helm interpolation.

foo:
  service:
    name: {{.Release.Name}}-service

When I dry run , I am getting this

apiVersion: v1
kind: ConfigMap
metadata:
  name: conf
data:
  application.yaml: "ei:\r\n  service:\r\n    name: {{.Release.Name}}-service"

but I want name: {{.Release.Name}}-service to contain actual helm release name.

Is it possible to do templating for external files using helm , if yes then how to do it ? I have gone through https://v2-14-0.helm.sh/docs/chart_template_guide/#accessing-files-inside-templates I didn't find something which solves my use case. I can also copy the content to config map yaml and can do interpolation but I don't want to do it. I want application.yml to be in a separate file, so that, it will be simple to deal with config changes..

-- aravind
kubernetes
kubernetes-helm

2 Answers

1/23/2020

Helm includes a tpl function that can be used to expand an arbitrary string as a Go template. In your case the output of ...AsConfig is a string that you can feed into the template engine.

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-conf
data:
{{ tpl (.Files.Glob "foo/*").AsConfig . | indent 2 }}

Once you do that you can invoke arbitrary template code from within the config file. For example, it's common enough to have a defined template that produces the name prefix of the current chart as configured, and so your config file could instead specify

foo:
  service:
    name: {{ template "mychart.name" . }}-service
-- David Maze
Source: StackOverflow

1/23/2020

As best I can tell, there is no recursive template evaluation available in helm (nor in Sprig), likely by design

However, in your specific case, if you aren't expecting the full power of golang templates, you can cheat and use Sprig's regexReplaceAllLiteral:

kind: ConfigMap
data:
{{/* here I have used character classes rather that a sea of backslashes
     you can use the style you find most legible */}}
{{ $myRx := "[{][{] *[.]Release[.]Name *[}][}]" }}
{{ regexReplaceAllLiteral $myRx (.Files.Glob "foo/*").AsConfig .Release.Name }}

If you genuinely need the full power of golang templates for your config files, then helm, itself, is not the mechanism for doing that -- but helmfile has a lot of fancy tricks for generating the ultimate helm chart that helm will install

-- mdaniel
Source: StackOverflow