My goal is as follows:
- Generate a CA certificate and private key once using Helm’s
genCA
function in a named template. - Use said CA to generate signed certificates for all microservices created by the subcharts.
Below is my unsuccessful attempt to implement this:
-
In
main/templates/_helpers.tpl
:{{/* Generate a common CA certificate for all microservices */}} {{- define "main.gen-ca-cert" -}} {{- if not (and .Values.global.CAKey .Values.global.CACertificate) }} {{- $ca := genCA "myapp-ca" 365 -}} {{- $_ := set .Values.global "CACertificate" ($ca.Cert | b64enc) -}} {{- $_ := set .Values.global "CAKey" ($ca.Key | b64enc) -}} {{- end -}} {{- end -}}
- The condition is supposed to ensure that the CA will be generated only once even if
main.gen-ca-cert
is referenced multiple times. After the CA is generated, the encoded key and certificate are stored as global values for subsequent invocations. - For visibility, I’ve created the following Secret template under
main/templates
:apiVersion: v1 kind: Secret type: kubernetes.io/tls metadata: name: ca-cert labels: release: {{ .Release.Name }} annotations: "helm.sh/hook": "pre-install" "helm.sh/hook-delete-policy": "before-hook-creation" data: tls.crt: {{ .Values.global.CACertificate }} tls.key: {{ .Values.global.CAKey }}
- The condition is supposed to ensure that the CA will be generated only once even if
-
In
subchart/templates/_helpers.tpl
, I useinclude
to invokemain.gen-ca-cert
and ensure the global variables are set before using them to generate a signed certificate:{{/* Generate certificates for the subchart's microservice */}} {{- define "subchart.gen-certs" -}} {{- $namespace := .Release.Namespace -}} {{ include "main.gen-ca-cert" . }} {{- $ca := buildCustomCert .Values.global.CACertificate .Values.global.CAKey -}} {{- $serviceName := "myservice" -}} {{- $serviceFQDN := printf "%s.%s.svc.cluster.local" $serviceName $namespace -}} {{- $altNames := list $serviceName $serviceFQDN -}} {{- $cert := genSignedCert $serviceName nil $altNames 365 $ca -}} tls.crt: {{ $cert.Cert | b64enc }} tls.key: {{ $cert.Key | b64enc }} ca.crt: {{ $ca.Cert | b64enc }} {{- end -}}
Then, I use
subchart.gen-certs
to populate a Secret undersubchart/templates
:apiVersion: v1 kind: Secret type: kubernetes.io/tls metadata: ... data: {{ include "subchart.gen-certs" . | indent 2 }}
Using this approach, helm install
finishes successfully but I’m getting a unique CA certificate for the subchart’s Secret resources, which implies genCA
was executed more than once despite my efforts to prevent it. My guess is that it’s either a context issue with how I set the global variables, or maybe you just can’t manipulate global variables in runtime and have them propagated to all subcharts the way I intended.
Notably, it does work when creating multiple secrets under the main chart, but the subcharts always end up with their own CA certificate.
Is there a way to get this working?
2