'Is it possible to neatly flatten a list of maps from values.yaml by selecting a key present in each map?

Suppose I have a values.yaml that contains the following arbitrary-length list of maps:

values.yaml
-----------
people:
  - name: "alice"
    age: 56
  - name: "bob"
    age: 42

One of the containers in my stack will need access to a list of just the names. (NAMES="alice,bob")

So far, I have come up with the following solution:

templates/_helpers.tpl
----------------------
{{- define "list.listNames" -}}
{{ $listStarted := false }}
{{- range .Values.people }}
{{- if $listStarted }},{{- end }}{{ $listStarted = true }}{{ .name }}
{{- end }}
{{- end }}
templates/configmap.yaml
------------------------
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  NAMES: '{{- include "list.listNames" . }}'

This solution works, but it feels inelegant. Looking through the Helm documentation, it seems like this would be the perfect use case for pluck in combination with join, but I haven't found a way to use .Values.people as an argument to that function.

Is there a cleaner way to do this?



Solution 1:[1]

There's a join function. I've two different solutions to utilize join:

Solution 1

I can't collect the names in a list. Therefore I use a dict and extract the keys later:

{{- define "list.listNames" -}}
{{- $map := dict }}
{{- range .Values.people }}
{{- $_ := set $map .name "" }}
{{- end }}
{{- keys $map | join "," }}
{{- end }}

This solution might change the order. Perhaps sortAlpha could fix this.

Solution 2

Because function must return a map, I need to add a key. Otherwise you can't convert to a dict by fromYaml:

templates/_helpers.tpl
----------------------
{{- define "list.listNames" -}}
items:
    {{- range .Values.people }}
    - {{ .name }}
    {{- end }}
{{- end }}

Then I convert to a dict object by fromYaml and join the list:

templates/configmap.yaml
------------------------
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- $items := include "list.listNames" . | fromYaml }}
  NAMES: {{ $items.items | join "," | quote }}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1