{{ If }} clause inside of range scope doesn't see values

8/14/2019

The task is to range over workers collection and if the current worker has autoscaling.enabled=true create an hpa for it.

I've tried to compare .autoscaling.enabled to "true" but it returned "error calling eq: incompatible types for comparison". Here people say that it actually means that .autoscaling.enabled is nil. So {{ if .autoscaling.enabled }} somehow doesn't see the variable and assumes it doesn't exist.

Values:

...
workers:
  - name: worker1
    command: somecommand1
    memoryRequest: 500Mi
    memoryLimit: 1400Mi
    cpuRequest: 50m
    cpuLimit: 150m
    autoscaling:
      enabled: false
  - name: worker2
    command: somecommand2
    memoryRequest: 512Mi
    memoryLimit: 1300Mi
    cpuRequest: 50m
    cpuLimit: 150m
    autoscaling:
      enabled: false
  - name: workerWithAutoscaling
    command: somecommand3
    memoryRequest: 600Mi
    memoryLimit: 2048Mi
    cpuRequest: 150m
    cpuLimit: 400m
    autoscaling:
      enabled: true
      minReplicas: 1
      maxReplicas: 5
      targetCPUUtilization: 50
      targetMemoryUtilization: 50
...

template:

...
{{- range .Values.workers }}
{{- if .autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  labels:
    ...
  name: "hpa-{{ .name }}-{{ $.Realeas.Name }}"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ .name }}
  minReplicas: {{ .minReplicas }}
  maxReplicas: {{ .maxReplicas }}
  metrics:
{{- with .targetCPUUtilization}}
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: {{ . }}
{{- end }}
{{- with .targetMemoryUtilization}}
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: {{ . }}
{{- end }}
---
{{- end }}
{{- end }}

I expect the manifest for one hpa that targets workerWithAutoscaling, but the actual output is totally empty.

-- Ruslan Timofieiev
kubernetes
kubernetes-helm

1 Answer

8/14/2019

Your use of {{- range .Values.workers }} and {{- if .autoscaling.enabled }} is fine. You are not getting any values because .minReplicas, .maxReplicas, etc, are inside .autoscaling scope.

See Modifying scope using with

Adding {{- with .autoscaling}} will solve the issue.

{{- range .Values.workers }}
{{- if .autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  labels:
  name: "hpa-{{ .name }}-{{ $.Release.Name }}"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ .name }}
{{- with .autoscaling}}
  minReplicas: {{ .minReplicas }}
  maxReplicas: {{ .maxReplicas }}
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: {{ .targetCPUUtilization}}
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: {{ .targetMemoryUtilization}}
{{- end }}
{{- end }}
{{- end }}

helm template .

---
# Source: templates/hpa.yaml

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  labels:
  name: "hpa-workerWithAutoscaling-release-name"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: workerWithAutoscaling
  minReplicas: 1
  maxReplicas: 5
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 50
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: 50
-- edbighead
Source: StackOverflow