helm templating with toYaml

6/10/2020

I have values.yml file that takes in a list of ports with this format and default values:

Ports:
  - number: 443
    protocol: http

The script that output the list of port to use as my input gives me this format:

port_list=$(./get_ports.sh)

output:

- 80
- 8080

I want the resulting rendered template to be

Ports:
  - number: 80
  - number: 8080

How would I accomplish this? I tried the following in my template file:

{{- with .Values.Ports }}
Ports:
  {{- toYaml . | nindent 8 }}
{{- end }}

using helm template and setting values.Ports=$port_list, it ended up giving me a pipe and an extra dash like below, which I do not know where they come from, how do I accomplish getting to the format I want above based on the input?

Ports:
|-
  - number: 80
  - number: 8080

As a bonus, I would also like to have a default protocol in my port list when the protocol isn't specified.

Ports:
  - number: 80
    protocol: http
  - number: 8080
    protocol: http

Is there a clean way to do this with just templating?

-- Jimmy Smith
kubernetes
kubernetes-helm
yaml

1 Answer

6/12/2020

First, you have to know about the YAML syntax about string. You can find it by searching on the internet. For example: see YAML Multiline.

| enables multiline string and - chops the trailing \n from the end of the string.

The reason for appearing |- is the output of the script get_ports.sh (is being treated as a single string). You can test this,

port_list=$(get_ports.sh)
# pass this to the `--set` flag in both of the following ways
# 01: pass the var $port_list
--set ports=$port_list
# 02: directly pass the value of the var $port_list
--set ports="- 80
- 8080"

For both of the tests you have the same output as follows:

ports:
|-
  - 80
  - 8080

If you put a newline at the end of the output of your script, then you will see the - has disappeared.

--set ports="- 80
- 8080
"

The output is like as following:

ports:
|
  - 80
  - 8080

Now try in a different way. Change your template to like this one:

{{- if .Values.ports }}
  {{- print "ports:" | nindent 2 }}
  {{- range $_, $p := .Values.ports }}
    - number: {{ $p }}
      protocol: http
  {{- end }}
{{- end }}

This template expects the value of your ports in the --set flag as a list (not a string). According to my knowledge at the time of writing this answer, to provide a list value in --set flag either of the followings can be used:

  • --set ports={80\,8080}
  • --set ports[0]=80,ports[1]=8080

Now the output is same as you want.

$ helm template test . --set ports={80\,8080}
ports:
  - number: 80
    protocol: http
  - number: 8080
    protocol: http

So all you need to process the output of get_ports.sh. That's it.

You may need to adjust the indentation in the template

-- Shudipta Sharma
Source: StackOverflow