4

I would like to convert a part of the structure in values.yaml to properties file in a config map.

Is it possible to convert a yaml structure like:

field1: value1
field2:
   field21: value21
   field22: value22

into

field1=value1
field2.field21=value21
field2.field22=value22

with Helm templating functions?

abinet
  • 2,552
  • 1
  • 15
  • 24

4 Answers4

4

You will need to bring your values under separate key and some Sprig Template Functions in your Configmap.

values.yaml

fields:
  field1: value1
  field2:
    field21: value21
    field22: value22

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: Configmap
data:
{{ range $key, $value := .Values.fields }}
  {{- if kindIs "map" $value -}}
  {{ $top:=$key }}
  {{- range $key, $value := $value }}
  {{ $top }}.{{ $key }}={{ $value }}
  {{- end -}}
  {{- else -}}
  {{ $key | indent 2}}={{ $value }}
  {{- end -}}
{{- end -}}

helm template . -x templates/configmap.yaml

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: Configmap
data:
  field1=value1
  field2.field21=value21
  field2.field22=value22

I suggest extracting this logic to _helpers.tpl file. You will need to add more logic if you have more nested configs.

edbighead
  • 5,607
  • 5
  • 29
  • 35
3

As a programming problem, this is a straightforward recursive call. You can use Go text/template templates like functions. The one trick here is that they only take a single parameter, so you need to use the sprig list function to pack multiple values into that parameter, and the text/template index function to get values back out.

{{- define "envify" -}}
{{- $prefix := index . 0 -}}
{{- $value := index . 1 -}}
{{- if kindIs "map" $value -}}
  {{- range $k, $v := $value -}}
    {{- template "envify" (list (printf "%s.%s" $prefix $k) $v) -}}
  {{- end -}}
{{- else -}}
{{ $prefix }}={{ $value }}
{{ end -}}

data:
{{ template "envify" (list "" .Values.fields) | indent 2 }}

This will work with arbitrarily deep nested values.

If you refer to standard Helm variables (.Release, .Values, ...) this also becomes tricky because the . variable is reused for the single template parameter (it also gets reused within the range loop). I tend to explicitly pass it as an additional template parameter.

{{- $top := index . 2 -}}
# from the {{ $top.Chart.Name }} Helm chart

{{/* in your ConfigMap proper */}}
{{ template "envify" (list "" .Values.fields .) }}
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • This as is was causing the the key to be prefixed with a dot. Changing `{{- $prefix := index . 0 -}}` to `{{- $prefix := trimPrefix "." (index . 0) -}}` resolved the issue. – cjackson Mar 13 '23 at 14:52
2

The recursive call to the same template is straightforward. The below snippet is working. It should convert values.yaml to configmap data as property.

{{- define "envify" -}}
{{- $prefix := index . 0 -}}
{{- $value := index . 1 -}}
{{- if kindIs "map" $value -}}
  {{- range $k, $v := $value -}}
    {{- if $prefix -}}
        {{- template "envify" (list (printf "%s.%s" $prefix $k) $v) -}}
    {{- else -}}
        {{- template "envify" (list (printf "%s" $k) $v) -}}
    {{- end -}}          
  {{- end -}}
{{- else -}}
{{ $prefix | indent 2 }}={{ $value }}
{{ end -}}
{{- end -}}
vivek_vara
  • 51
  • 3
2

The answers here weren't quite enough for me, so I took them as a baseline and improved them until I had something that worked.

I still wanted the recursive reading of any properties under some sort of key in my values.yaml, but I wanted it to be formatted for use with dotenv.

Here's what I came up with:

values.yaml

config:
  database:
    name: my-db
    host: my-db-host
    port: 5432

ConfigMap

data:
  .env: |-
    {{- include "envify" (list "" .Values.config . ) | nindent 4 }}

Template:

{{- define "envify" -}}
{{- $prefix := index . 0 -}}
{{- $value := index . 1 -}}
{{- if kindIs "map" $value -}}
  {{- range $k, $v := $value -}}
    {{- if $prefix -}}
        {{- template "envify" (list (printf "%s_%s" $prefix $k | upper) $v) -}}
    {{- else -}}
        {{- template "envify" (list (printf "%s" $k) $v) -}}
    {{- end -}}
  {{- end -}}
{{- else -}}
{{ $prefix }}={{ $value }}
{{ end -}}
{{- end -}}

Output:

data:
  .env: |-
    DATABASE_NAME=my-db
    DATABASE_HOST=my-db-host
    DATABASE_PORT=5432

Hopefully this helps someone.

McFlurriez
  • 513
  • 6
  • 17