Helm charts nested loops

6/5/2018

Trying to generate deployments for my helm charts by using this template

{{- range .Values.services }}
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp-{{ . }}
spec:
  replicas: {{ .replicaCount }}
  template:
    metadata:
      labels:
        app: myapp-{{ . }}
        chart: myapp-{{ $.Values.cluster }}-{{ $.Values.environment }}
    spec:
      containers:
      - name: myapp-{{ . }}
        image: {{ $.Values.containerRegistry }}/myapp-{{ . }}:latest
        ports:
        - containerPort: {{ .targetPort }}
        env:
  {{- with .environmentVariables }}
  {{ indent 10 }}
  {{- end }}
      imagePullSecrets:
       - name: myregistry
{{- end }}

for 2 of my services. In values.yaml I got

environment: dev

cluster: sandbox

ingress:
  enabled: true

containerRegistry: myapp.io

services:
- backend:
    port: 80
    targetPort: 8080
    replicaCount: 1
    environmentVariables:
      - name: SOME_VAR
        value: "hello"
- web:
    port: 80
    targetPort: 8080
    replicaCount: 1
    environmentVariables:
      - name: SOME_VAR
        value: "hello"

... but the output is not being properly formatted

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp-map[backend:map[replicaCount:1 targetPort:8080 environmentVariables:[map[name:SOME_VAR value:hello] port:80]]

instead of

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp-web
(...)

and another config

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp-backend
(...)

what functions can I use or some different data structure? None of the references (i.e. .environmentVariables are working correctly)

-- FRC
kubernetes
kubernetes-helm
templates

1 Answer

6/6/2018

I think you should reconsider the way the data is structured, this would work better:

  services:
  - name: backend
    settings:
      port: 80
      targetPort: 8080
      replicaCount: 1
      environmentVariables:
        - name: SOME_VAR
          value: "hello"

  - name: web
    settings:
      port: 80
      targetPort: 8080
      replicaCount: 1
      environmentVariables:
        - name: SOME_VAR
          value: "hello"

And your Deployment to look like this:

{{- range .Values.services }}
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp-{{ .name }}
spec:
  replicas: {{ .settings.replicaCount }}
  template:
    metadata:
      labels:
        app: myapp-{{ .name }}
    spec:
      containers:
      - name: myapp-{{ .name }}
        image: {{ $.Values.containerRegistry }}/myapp-{{ .name }}:latest
        ports:
        - containerPort: {{ .settings.targetPort }}
        env:
  {{- with .settings.environmentVariables }}
  {{ toYaml . | trim | indent 6 }}
  {{- end }}
      imagePullSecrets:
       - name: myregistry
{{- end }}

would actually create two deployments, by adding the --- separator.

-- iomv
Source: StackOverflow