Helm: generate comma separated list

31,469

Solution 1

For those from 2020+ it now can be achieved as simple as that:

{{ join "," .Values.some.array }}

It produces the correct output: value: "test1,test2,test3"

At least it works with (more or less) recent versions of helm-cli:

Client: &version.Version{SemVer:"v2.16.2", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}

Solution 2

Another quick way of doing it:

{{- define "helm-toolkit.utils.joinListWithComma" -}}
{{- $local := dict "first" true -}}
{{- range $k, $v := . -}}{{- if not $local.first -}},{{- end -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}}
{{- end -}}

If you give this input like:

test:
- foo
- bar

And call with:

{{ include "helm-toolkit.utils.joinListWithComma" .Values.test }}

You'll get the following rendered:

foo,bar

This is from OpenStack-Helm's Helm-toolkit chart, which is a collection of utilities for similar purposes.

Solution 3

I faced with the same problem and your solution with dictionary saved my day. It's a good workaround and it can be just a little simpler:

{{- define "zkservers" -}}
{{- $zk := dict "servers" (list) -}}
{{- range int . | until -}}
{{- $noop := printf "zk-%d.zookeeper" . | append $zk.servers | set $zk "servers" -}}
{{- end -}}
{{- join "," $zk.servers -}}
{{- end -}}

Solution 4

You're currently defining a new varialbe in the scope of the list while you want to alter the existing value.

In order to fix your bug, you only need to change the way you assign the value to $zkservers:

    - {{- $zkservers := print "zk-" . ".zookeeper" | append $zkservers -}}
    + {{- $zkservers = print "zk-" . ".zookeeper" | append $zkservers -}}  

which gives you the following script:

{{- define "zkservers" -}}
{{- $zkservers := list -}}
{{- range int . | until -}}
{{- $zkservers = print "zk-" . ".zookeeper" | append $zkservers -}}
{{- end -}}
{{- join "," $zkservers -}}
{{- end -}}

With this slight modification, {{ include "zkservers" 3 }}gives you the output zk-0.zookeeper,zk-1.zookeeper,zk-2.zookeeper

Solution 5

I was doing the same but on elasticsearch helm chart. Please find my example

values.yml:

...
replicaCount: 3
...

StatefulSets.yaml:

...
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.registry_address }}/{{ .Values.image.name }}:{{ .Chart.AppVersion }}"
          env:
            - name: ELASTICSEARCH_CLUSTER_NAME
              value: "{{ .Values.env.ELASTICSEARCH_CLUSTER_NAME }}"
            - name: ELASTICSEARCH_DISCOVERY_ZEN_PING_UNICAST_HOSTS
              value: "{{ template "nodes" .Values }}"
...

_helpers.tpl:

{{/* vim: set filetype=mustache: */}}

{{- define "nodes" -}}
{{- $nodeCount := .replicaCount | int }}
  {{- range $index0 := until $nodeCount -}}
    {{- $index1 := $index0 | add1 -}}
elasticsearch-{{ $index0 }}.elasticsearch{{ if ne $index1 $nodeCount }},{{ end }}
  {{- end -}}
{{- end -}}

This produces a comma separated list:

...
            - name: ELASTICSEARCH_DISCOVERY_ZEN_PING_UNICAST_HOSTS
              value: "elasticsearch-0.elasticsearch,elasticsearch-1.elasticsearch,elasticsearch-2.elasticsearch"

...
Share:
31,469

Related videos on Youtube

alfred
Author by

alfred

Updated on April 09, 2020

Comments

  • alfred
    alfred about 4 years

    Using Helm templates, I'm trying to generate a list of server names based on a number in values.yaml. The dot for this template is set to the number (its a float64).

    {{- define "zkservers" -}}
    {{- $zkservers := list -}}
    {{- range int . | until -}}
    {{- $zkservers := print "zk-" . ".zookeeper" | append $zkservers -}}
    {{- end -}}
    {{- join "," $zkservers -}}
    {{- end -}}
    

    For an input of, say, 3 I'm expecting this to produce:

    zk-0.zookeeper,zk-1.zookeeper,zk-2.zookeeper
    

    It produces nothing.

    I understand that the line within the range block is a no-op since the variable $zkservers is a new variable each time the loop iterates. It is not the same variable as the $zkservers in the outer scope.

    I hope the intention is clear of what I want to do. I am at a loss how to do it.

    Anyone know how to do this with Helm templates?

  • Matt
    Matt about 4 years
    Nice, simpler than the dict shenanigans
  • Miguel Ferreira
    Miguel Ferreira almost 4 years
    This is definitely the best answer as of 2020
  • Ed Randall
    Ed Randall almost 4 years
    Found github.com/Masterminds/sprig/tree/master/docs which helps explain how this template language works, but still struggling with | append $zk.servers | set $zk "servers"
  • David S.
    David S. over 3 years
    This does not cover how you would concatenate for each element zk-i.zookeepr where i would be the original array element
  • Dark_eye
    Dark_eye over 3 years
    And it continues to be the correct answer in 2021
  • Paul Miller
    Paul Miller over 3 years
    Strange I don't see this documented on the helm function list. helm.sh/docs/chart_template_guide/function_list
  • Illya Doos
    Illya Doos over 3 years
    @PaulMiller Indeed. I think it's better to turn to sprig library documentation when it comes to helm3 templating, since most functions are taken from there AFAIK: godoc.org/github.com/Masterminds/sprig Helm maintainers also mention the original docs at the bottom of the document you've provided: Note, the documentation for many of these functions come from Sprig. Sprig is a template function library available to Go applications.