Helm with nested lists using range - kubernetes

I have the following content in values.yaml and virtualservice.yaml:
I want to create template file using above value but getting error while helm rendenring template.
values.yaml:
istio:
enabled: true
virtualService:
enabled: true
virtualServices:
"0":
name: hello-app
gateways:
- gateway-new
hosts:
- prod.abc.com
apps:
name: primary
path: "/api"
routes:
"0":
weight: 100
port: 8080
name: hello-app
"1":
weight: 0
port: 8080
name: hello-app-canary
"1":
name: hello-app-internal
gateways:
- mesh
hosts:
- hello-app.test.prod.svc.cluster.local
apps:
name: internal
path: "/api"
routes:
"0":
weight: 100
port: 9081
name: hello-app
"1":
weight: 0
port: 9081
name: hello-app-canary
virtualservice.yaml:
{{- if ((.Values.istio).enabled) }}
{{- if ((.Values.istio.virtualService).enabled) }}
{{- range $key, $value := .Values.istio.virtualService.virtualServices }}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: {{ .name }}
namespace: {{ $.Release.Namespace }}
labels:
{{ include "common.labels" $ | indent 4 }}
spec:
gateways:
{{- range .gateways }}
- {{.}}
{{- end }}
hosts:
{{- range .hosts }}
- {{.}}
{{- end }}
http:
{{- range $app := $value.apps }}
- match:
- uri:
prefix: "/{{ $app.path }}"
name: {{ $app.name }}
route:
{{- range $route := $app.routes }}
- destination:
host: {{ $route.name }}
port:
number: {{ $route.port }}
weight: {{ $route.weight }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
How do I iterate if I have more than one list using range? With the above template, I am getting the error:
at <$app.path>: can't evaluate field path in type interface {}
Any help is highly appreciated.

First of all, it looks like the virtual service "1" has one extra indent (right now it is under virtual service "0" section, but it should be under "virtualServices").
Moreover, If you want to iterate over the apps of each virtual service, the apps field should be a list, but right now it is a dictionary. Therefore, when you iterate with range $app := $value.apps you are actually iterating over the fields of apps, which leads to the error you are getting.
Here's the fixed version of values.yam:
istio:
enabled: true
virtualService:
enabled: true
virtualServices:
"0":
name: hello-app
gateways:
- gateway-new
hosts:
- prod.abc.com
apps:
- name: primary
path: "/api"
routes:
"0":
weight: 100
port: 8080
name: hello-app
"1":
weight: 0
port: 8080
name: hello-app-canary
"1":
name: hello-app-internal
gateways:
- mesh
hosts:
- hello-app.test.prod.svc.cluster.local
apps:
- name: internal
path: "/api"
routes:
"0":
weight: 100
port: 9081
name: hello-app
"1":
weight: 0
port: 9081
name: hello-app-canary

Related

Helm has/merge option for overrides

I am trying to create a template whereby values have a default set of service names, unless they are overriden. example:
default:
service:
- name: nginx1
service: "dev-nginx1"
port: 8080
- name: nginx2
service: "dev-nginx2"
port: 8080
identifiers:
- identifier: "cust1"
- identifier: "cust2"
- identifier: "cust3"
overrides:
identifiers:
- identifier: "cust2"
service:
- name: nginx4
service: "cust2-nginx4"
port: 8080
- name: nginx12
service: "cust2-nginx12"
port: 8080
Where the above would yield:
---
identifier: cust1
service: dev-nginx
port: 8080
service: dev-nginx2
port: 8080
---
identifier: cust2
service: cust2-nginx4
port: 8080
service: cust2-nginx12
port: 8080
---
identifier: cust3
service: dev-nginx
port: 8080
service: dev-nginx2
port: 8080
I have tried the following, but i'm getting in a mess with the iterations in the incorrect place. Is there an easier way to accomplish this in helm with some sort of merge function?
{{- range $key, $values := $.Values.default.identifiers -}}
{{- range $overrideKey, $overrideValues := $.Values.overrides.identifiers -}}
{{ if eq $values.identifier $overrideValues.identifier }}
---
identifier: {{ $values.identifier }}
{{- range $value := $overrideValues.service }}
service: {{ $value.name }}
port: {{ $value.port }}
{{- end }}
{{ else }}
---
identifier: {{ $values.identifier }}
{{- range $value := $overrideValues.service }}
service: {{ $value.name }}
port: {{ $value.port }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

I want use helm range for below code to iterate its with proper indentation

I want to iterate the list from Values.yaml through range in helm.
So how to use the range function in helm for below list?
Values.yaml
Service:
- name: jenkins-db
protocol: TCP
port: 8000
- name: jenkins-ui
protocol: TCP
port: 9000
Thanks in advance
Try out this:
{{- range .Values.Service }}
apiVersion: v1
kind: Service
metadata:
name: {{ .name }}
spec:
selector:
app: {{ .name }}
ports:
- protocol: {{ .protocol }}
port: {{ .port }}
targetPort: {{ .port }}
---
{{- end }}

Helm chart ingress.yaml return error error nil pointer evaluating interface

Following a task on using helm chart, but was not able to install ingress.yaml. It is complaining about a class. The error is pasted below. Is there anything am missing here?
ingress/templates/ingress.yaml:6:43: executing "ingress/templates/ingress.yaml" at <.Values.ingress.annotations.class>: nil pointer evaluating interface {}.class
The code for the ingress.yaml is below :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.ingress.name }}
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.annotations.class }}
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number }}
{{- end }}
{{- end }}
The values in the values.yaml is :
ingress:
name: ingress-service
replicaCount: 1
annotations:
class: nginx
hosts:
- host: chart-example.local
paths:
- path: /
backend:
service:
name: ServiceName
port:
number: 8080
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.ingress.name }}
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.annotations.class }}
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: Prefix
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port }}
{{- end }}
{{- end }}

How to override ingress rules helm-chart template

Here is my ingress.yml file
spec:
rules:
- host: {{- if .Values.ingress.host }} {{ tpl .Values.ingress.host . }} {{- end }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ssl-redirect
port:
name: use-annotation
{{- range $port := .Values.container.app.port }}
- path: {{ tpl $port.path $ }}
pathType: Prefix
backend:
service:
name: {{ $.Release.Name }}
port:
number: {{ int $port.port }}
{{- end }}
{{ end }}
I want to override this rules some service here is what I try to do in my values.yml file
ingress:
scheme: internal
host: test.com
paths:
- path: /
pathType: Prefix
backend:
service:
name: ssl-redirect
port:
name: use-annotation
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 3000
but after I deploy it's not override at all may be in wrong format not sure
UPDATE
I try to this way but It still didn't override rules in ingress
hosts:
- host: test.com
paths:
- path: /test
pathType: Prefix
backend:
service:
name: ssl-redirect
port:
name: use-annotation
- path: /test
pathType: Prefix
backend:
service:
name: test-dev
port:
number: 3000
ingress.yaml should be something like
kind: Ingress
metadata:
name: {{ $name }}
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with $_annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ . }}
backend:
serviceName: {{ $name }}
servicePort: 80
{{- end }}
{{- end }}
{{- end }}
values.yaml
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: test.example.io
paths: [/path]
# tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
Another example :
Ingress.yaml : https://github.com/helm/charts/blob/master/stable/ghost/templates/ingress.yaml
values.yaml : https://github.com/helm/charts/blob/master/stable/ghost/values.yaml
i'm assuming that this is not the whole ingress.yaml template because if it is, you are missing the apiVersion, kind and metadata block entirely. :)
helm can create a baseline chart with helm create <chartName>. in this baseline chart, there is a ingress.yaml template with a corresponding values.yaml which works just fine and follows helm best practices. i recommend you use that one to ease and speed up your workflow instead of writing your own template, even if you do not understand it at first. the generated templates by helm create are worth studying because there is a lot to learn from them and they are a good showcase of how to solve some common problems when writing helm charts and how to follow best practices for labeling, annotations etc.
anyways, if you want to stick to that data structure and create your own template, this is the template that worked during my tests. i used the helm template command to check if there are any rendering errors whilst providing your values.
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}
spec:
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
{{- range .Values.ingress.paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service: {{ .backend.service | toYaml | nindent 14 }}
{{- end }}

error parsing templates/deployment.yaml: json: line 1: invalid character '{' looking for beginning of object key string

i'm getting an following error, when i try to deploy nexus using kubernetes.
Command: kubectl appy -f templates/deployment.yaml
error parsing templates/deployment.yaml: json: line 1: invalid
character '{' looking for beginning of object key string
Did anybody faced this issue?
Please find the below code which i'm trying:
{{- if .Values.localSetup.enabled }}
apiVersion: apps/v1
kind: Deployment
{{- else }}
apiVersion: apps/v1
kind: StatefulSet
{{- end }}
metadata:
labels:
app: nexus
name: nexus
spec:
replicas: 1
selector:
matchLabels:
app: nexus
template:
metadata:
labels:
app: nexus
spec:
{{- if .Values.localSetup.enabled }}
volumes:
- name: nexus-data
persistentVolumeClaim:
claimName: nexus-pv-claim
- name: nexus-data-backup
persistentVolumeClaim:
claimName: nexus-backup-pv-claim
{{- end }}
containers:
- name: nexus
image: "quay.io/travelaudience/docker-nexus:3.15.2"
imagePullPolicy: Always
env:
- name: INSTALL4J_ADD_VM_PARAMS
value: "-Xms1200M -Xmx1200M -XX:MaxDirectMemorySize=2G -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap"
resources:
requests:
cpu: 250m
memory: 4800Mi
ports:
- containerPort: {{ .Values.nexus.dockerPort }}
name: nexus-docker-g
- containerPort: {{ .Values.nexus.nexusPort }}
name: nexus-http
volumeMounts:
- mountPath: "/nexus-data"
name: nexus-data
- mountPath: "/nexus-data/backup"
name: nexus-data-backup
{{- if .Values.useProbes.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.nexus.livenessProbe.path }}
port: {{ .Values.nexus.nexusPort }}
initialDelaySeconds: {{ .Values.nexus.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.nexus.livenessProbe.periodSeconds }}
failureThreshold: {{ .Values.nexus.livenessProbe.failureThreshold }}
{{- if .Values.nexus.livenessProbe.timeoutSeconds }}
timeoutSeconds: {{ .Values.nexus.livenessProbe.timeoutSeconds }}
{{- end }}
readinessProbe:
httpGet:
path: {{ .Values.nexus.readinessProbe.path }}
port: {{ .Values.nexus.nexusPort }}
initialDelaySeconds: {{ .Values.nexus.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.nexus.readinessProbe.periodSeconds }}
failureThreshold: {{ .Values.nexus.readinessProbe.failureThreshold }}
{{- if .Values.nexus.readinessProbe.timeoutSeconds }}
timeoutSeconds: {{ .Values.nexus.readinessProbe.timeoutSeconds }}
{{- end }}
{{- end }}
{{- if .Values.nexusProxy.enabled }}
- name: nexus-proxy
image: "quay.io/travelaudience/docker-nexus-proxy:2.4.0_8u191"
imagePullPolicy: Always
env:
- name: ALLOWED_USER_AGENTS_ON_ROOT_REGEX
value: "GoogleHC"
- name: CLOUD_IAM_AUTH_ENABLED
value: "false"
- name: BIND_PORT
value: {{ .Values.nexusProxy.targetPort | quote }}
- name: ENFORCE_HTTPS
value: "false"
{{- if .Values.localSetup.enabled }}
- name: NEXUS_DOCKER_HOST
value: {{ .Values.nexusProxy.nexusLocalDockerhost }}
- name: NEXUS_HTTP_HOST
value: {{ .Values.nexusProxy.nexusLocalHttphost }}
{{- else }}
- name: NEXUS_DOCKER_HOST
value: {{ .Values.nexusProxy.nexusDockerHost}}
- name: NEXUS_HTTP_HOST
value: {{ .Values.nexusProxy.nexusHttpHost }}
{{- end }}
- name: UPSTREAM_DOCKER_PORT
value: {{ .Values.nexus.dockerPort | quote }}
- name: UPSTREAM_HTTP_PORT
value: {{ .Values.nexus.nexusPort | quote }}
- name: UPSTREAM_HOST
value: "localhost"
ports:
- containerPort: {{ .Values.nexusProxy.targetPort }}
name: proxy-port
{{- end }}
{{- if .Values.nexusBackup.enabled }}
- name: nexus-backup
image: "quay.io/travelaudience/docker-nexus-backup:1.4.0"
imagePullPolicy: Always
env:
- name: NEXUS_AUTHORIZATION
value: false
- name: NEXUS_BACKUP_DIRECTORY
value: /nexus-data/backup
- name: NEXUS_DATA_DIRECTORY
value: /nexus-data
- name: NEXUS_LOCAL_HOST_PORT
value: "localhost:8081"
- name: OFFLINE_REPOS
value: "maven-central maven-public maven-releases maven-snapshots"
- name: TARGET_BUCKET
value: "gs://nexus-backup"
- name: GRACE_PERIOD
value: "60"
- name: TRIGGER_FILE
value: .backup
volumeMounts:
- mountPath: /nexus-data
name: nexus-data
- mountPath: /nexus-data/backup
name: nexus-data-backup
terminationGracePeriodSeconds: 10
{{- end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: nexus-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 32Gi
storageClassName: {{ .Values.persistence.storageClass }}
- metadata:
name: nexus-data-backup
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 32Gi
storageClassName: {{ .Values.persistence.storageClass }}
{{- end }}
Any leads would be appreciated!
Regards
Mani
The template you provided here is the part of helm chart, which can be deployed using helm-cli, not using kubectl apply.
More info on using helm is here.
You can also get the instructions to install nexus using helm in this official stable helm chart.
Hope this helps.