Search code examples
kuberneteskubernetes-helm

Helm loop with specific values


I want to build multiple KafkaConnector template from values.yaml, but with specic map

the values.yaml instance :

Definition:
  Information:
    - db.user:
        name: aaa
        key: bbb
    - db.secret:
        name: aaa
        key: ccc
    - db.host: hosntame
    - db.port: 1234
  Information1:
    - db.user:
        name: zzz
        key: yyy
    - db.secret:
        name: zzz
        key: vvv
    - db.host: hosntame1
    - db.port: 1235

connector.yaml file

{{- range .Value.Definition }}
---
apiVersion: {{ $.Values.apiVersion }}
kind: KafkaConnector
metadata:
  name: {{ include "common.names.fullname" $ }}-{{ .name }}    
spec:
  class: need
  config: 
  {{ range $k, $v := .Value }}
  {{ $k }}:
    {{ if eq  $k "db.secret" }}
    ${secrets:{{ $v.name }}/{{ $v.value }}}
    {{ else }}
    {{ $v.value }}
  {{ end }}
{{ end }}
{{ end }}

At the end, the output I would like something like that :

apiVersion: apps/v1
kind: KafkaConnector
metadata:
  name: connect-Information
spec:
  class: need
  config:
    db.user: bbb
    db.secret: ${secrets:aaa/ccc}
    db.hostname: hostname
    db.port: 1234

apiVersion: apps/v1
kind: KafkaConnector
metadata:
  name: connect-Information1
spec:
  class: need
  config:
    db.user: yyy
    db.secret: ${secrets:zzz/vvv}
    db.hostname: hostname1
    db.port: 1235

I succced to loop over one time with only information, but I cannot to loop over two key information/information1

because, I need to make two loop.


Solution

  • To solve this problem, you need to organize your values into a suitable data structure. Then, you should use a range to iterate through this list or dictionary appropriately.

    Here is a solution:

    values.yaml

    Definition:
      Information:
        db.user:
          name: aaa
          key: bbb
        db.secret:
          name: aaa
          key: ccc
        db.host: hosntame
        db.port: 1234
      Information1:
        db.user:
          name: zzz
          key: yyy
        db.secret:
          name: zzz
          key: vvv
        db.host: hosntame1
        db.port: 1235
    

    Note that in the values.yaml, a dictionary is used under Definition.Information instead of the original list structure. This change was made because the original structure had non-uniform keys, making the use of a list unnecessary. Using a dictionary is a better approach.

    connector.yaml

    {{- range $infoKey, $infoVal := .Values.Definition }}
    ---
    apiVersion: {{ $.Values.apiVersion }}
    kind: KafkaConnector
    metadata:
      name: test-{{ $infoKey }}    
    spec:
      class: need
      config:  
        {{- range $k, $v := $infoVal }}
        {{- if eq $k "db.secret" }}
        {{ $k }}: ${secrets: {{ $v.name }}/{{ $v.key }}}
        {{- else if eq $k "db.user" }}
        {{ $k }}: {{ $v.key }}
        {{- else }}
        {{ $k }}: {{ $v }}
        {{- end }}
        {{- end }}
    {{- end }}
    

    Additionally, you need to be mindful of using the "-" symbol within {{- }} to remove unnecessary whitespace characters appropriately.

    output

    ---
    apiVersion: 
    kind: KafkaConnector
    metadata:
      name: test-Information    
    spec:
      class: need
      config:
        db.host: hosntame
        db.port: 1234
        db.secret: ${secrets: aaa/ccc}
        db.user: bbb
    ---
    apiVersion: 
    kind: KafkaConnector
    metadata:
      name: test-Information1    
    spec:
      class: need
      config:
        db.host: hosntame1
        db.port: 1235
        db.secret: ${secrets: zzz/vvv}
        db.user: yyy
    

    ps: helm doc: In addition to lists and tuples, range can be used to iterate over collections that have a key and a value (like a map or dict).