In a helm template how can i use items in 1 list to iterate over another list
i want to pre-populate a kubernetes cluster with namespaces and their respective secrets for our apps and services. For that i would like to be able to specify 2 lists, 1 list with secrets, and 1 list with namespaces. Each namespace in the list has a list of secrets. Like this values.yaml:
secrets:
- name: secret1
data: key1
- name: secret2
data: key2
- name: secret3
data: key3
namespaces:
- name: app1
secrets:
- secret1
- secret2
- name: app2
secrets:
- secret1
- secret3
Then i want to loop over namespaces to create the namespaces, like:
{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
name: {{ $namespaces.name }}
---
{{- end }}
In that loop i want another loop inside this loop that creates the secrets per namespace with the data from the secrets list. A bit like this:
{{- range $secrets := .secrets }}
apiVersion: v1
kind: Secret
metadata:
name: {{ .name }}
namespace: {{ $namespaces.name }}
type: kubernetes.io/tls
data: $secrets.data
---
{{- end }}
But if i put that loop inside the namespace loop, it just creates all secrets in the secrets list in all namespaces.
How can i make the loop only create the secrets specified in the namespaces list?
I think it can be done with the go template index function, but i don't know how.
Solution 1:
I have made reproduction on your problem and find answer for that.
Your example
I used your yamls to create namespaces and changed the second one so it's actually work now.
values.yaml
secrets:
- name: secret1
data: key1
- name: secret2
data: key2
- name: secret3
data: key3
namespaces:
- name: app1
secrets:
- secret1
- secret2
- name: app2
secrets:
- secret1
- secret3
templates/namespaces.yaml
{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
name: {{ $namespaces.name }}
---
{{- end }}
{{- range $namespace := .Values.namespaces }}
{{- range $secret := $namespace.secrets }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ $secret }}
namespace: {{ $namespace.name }}
type: kubernetes.io/tls
data: $secrets.data
---
{{- end }}
{{- end }}
Result:
COMPUTED VALUES:
namespaces:
- name: app1
secrets:
- secret1
- secret2
- name: app2
secrets:
- secret1
- secret3
secrets:
- data: key1
name: secret1
- data: key2
name: secret2
- data: key3
name: secret3
HOOKS:
MANIFEST:
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
name: app1
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
name: app2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret1
namespace: app1
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret2
namespace: app1
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret1
namespace: app2
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
name: secret3
namespace: app2
type: kubernetes.io/tls
data: $secrets.data
My idea of doing that
Instead of creating secrets for namespaces, do it the other way around, create secrets and add namespaces to them.
values.yaml
Secret1:
- namespace1
- namespace2
Secret2:
- namespace2
templates/namespaces.yaml
{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
name: {{ $namespaces.name }}
---
{{- end }}
templates/secrets.yaml
{{- range .Values.Secret1 }}
---
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: null
name: secret1
namespace: {{ . }}
{{- end}}
{{- range .Values.Secret2 }}
---
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: null
name: secret2
namespace: {{ . }}
{{- end}}
Result:
COMPUTED VALUES:
Secret1:
- namespace1
- namespace2
Secret2:
- namespace2
namespaces:
- name: namespace1
- name: namespace2
HOOKS:
MANIFEST:
---
# Source: mychart/templates/namespaces2.yaml
apiVersion: v1
kind: Namespace
metadata:
name: namespace1
---
# Source: mychart/templates/namespaces2.yaml
apiVersion: v1
kind: Namespace
metadata:
name: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I=
username: ZGV2dXNlcg==
kind: Secret
metadata:
creationTimestamp: null
name: secret1
namespace: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
data:
password: ZGV2dXNlcg==
username: UyFCXCpkJHpEc2I=
kind: Secret
metadata:
creationTimestamp: null
name: secret2
namespace: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I=
username: ZGV2dXNlcg==
kind: Secret
metadata:
creationTimestamp: null
name: secret1
namespace: namespace1
More informations about Flow Control(if,else if,range) can be found here.