I have the following values.yaml
ingresses:
- name: public
class: "nginx"
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 122m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "7"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
labels: {}
rules:
- host: example.com
http:
paths:
- path: /asd/as
pathType: ImplementationSpecific
backend:
service:
name: one
port:
number: 8080
- backend:
service:
name: log
port:
number: 8081
path: /path/log
pathType: ImplementationSpecific
- backend:
service:
name: got
port:
number: 8082
path: /api/got
pathType: ImplementationSpecific
tls:
- hosts:
- example.com
secretName: cert
- name: public
annotations:
labels: {}
rules:
- host: example1.com
http:
paths:
- backend:
service:
name: web
port:
number: 8090
pathType: ImplementationSpecific
tls:
- hosts:
- example1.com
secretName: qwe
and I have the following ingress file:
{{- $top := . -}}
{{- range $ingress := .Values.ingresses }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $ingress.name }}
namespace: {{ $ingress.namespace }}
{{- with $ingress.annotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- if and $ingress.class (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ $ingress.class }}
{{- end }}
{{- if $ingress.tls }}
tls:
{{- range $ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range $ingress.rules }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
{{- if and .path (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
- path: {{ .path }}
{{ end }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ .backend.service.name }}
port:
number: {{ .backend.service.port.number}}
{{- end }}
{{- end }}
{{- end }}
This only generates one ingress (whichever is the last one in values files). I tried using range $ingress := .Values.ingress
but it keeps giving me an error whenever I try $ingress.name . What changes do I make to the ingress.yaml to be able to deploy both these ingresses.
Edit: Made edits based on David's answer.
CodePudding user response:
You need to break the two separate ingress configurations up in the Helm values somehow. Right now they're in a single map object under ingress:
, so .Values.ingress.name
for example only has one value rather than being something you can iterate over.
A YAML list here makes sense:
# values.yaml
ingresses:
- name: example-com
class: nginx
rules: [...]
- name: example1-com
class: nginx
rules: [...]
Then you can iterate over this list with a range
loop. The important thing to know about a range
loop is that it rebinds the .
special variable, which is the base of constructs like .Values
; that means that you need to save the original value of .
outside the loop (the $
special variable may work as well). You can generate multiple Kubernetes objects in a single Helm template file so long as each begins with the YAML ---
start-of-document marker (and it's valid to generate no output at all).
{{-/* save the original value of . */-}}
{{- $top := . -}}
{{-/* iterate over the ingress configurations */-}}
{{- range $ingress := .Values.ingresses }}
---
{{-/* your existing conditionals can go here, simplifying */}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
{{-/* this comes from the per-ingress config */}}
{{- with $ingress.annotations }}
annotations: {{- toYaml . | nindent 4 }}
{{- end }}
{{-/* if you need to use "standard" helper functions, make sure
to pass the saved $top value as their parameter */}}
name: {{ include "mychart.fullname $top }}-{{ $ingress.name }}
spec: { ... }
{{- end }}
You also may want to reconsider how much of this is appropriate to include in arbitrarily-configurable values. Rather than essentially write out the entire Ingress object in Helm values, you may find it easier to write out things like the path mappings in the template files themselves, and have a few high-level controls ("enabled", "host name", "TLS secret name") exposed. Things like the backend service name and port will correspond to other things in your chart and you may need to compute the service name; someone just installing your chart shouldn't need to configure this.