I'd like to leverage a named template in a helm chart to build a string whose value ultimately is going to be the aws-load-balancer-controller annotation for alb.ingress.kubernetes.io/certificate-arn
, which is just a comma separated list of applicable ACM certs.
In my values.yaml I support override for additional certs as an object like this:
# in values.yaml as default
ingress.additional_certs: {}
# as an override of the above:
ingress.additonal_certs:
- arn: "arn:aws:acm:us-west-2:xxxxxxxxxxx:certificate/357ac969-643b-4424-a028-57183e02a765"
host: "somedomain.sub.com"
- arn: "arn:aws:acm:us-west-2:xxxxxxxxxxx:certificate/357ac969-643b-4424-a028-57183e02a764"
host: "someotherdomain.foo.com"
The idea is you're likely going to have a different cert for each domain, so it's easier for the end user to keep track of what goes to what. By calling the override "additional_certs", it follows there's a default ACM cert used so anything under "additional_certs" is just tacked on to the annotation string and also enumerated properly under ingress.spec.rules
.
The problem I'm having a lot of trouble wrapping my head around is how I can take a base string (in this case, the default ACM ARN) and build onto it. Conceptually this is just a simple string building exercise, for example:
# in pseudocode
var cert_arns = "arn:aws:acm:us-west-2:xxxxxxxxxxx:certificate/357ac969-643b-4424-a028-57183e02a761"
cert_arns += "," + ingress.additional_certs.arn[0]
# so cert_arns ostensibly becomes "arn:aws:acm:us-west-2:xxxxxxxxxxx:certificate/357ac969-643b-4424-a028-57183e02a761,arn:aws:acm:us-west-2:xxxxxxxxxxx:certificate/357ac969-643b-4424-a028-57183e02a765"
To be frank, I'm not even sure how to try doing this with a named template. Most examples using range
tend to be for looping over filling in yaml like labels
. How one would go about simply iterating over a range and tacking on the value (in this case it'd be something like range $k, $v := .Values.ingress.additional_certs
, so $v.arn
) simply isn't clicking and I haven't stumbled across any examples of doing string building.
If there are better methods of accomplishing this that isn't a named template I'm all ears.
Helm has concepts of "lists" and "dictionaries", but there aren't a lot of manipulation functions that work on them. You could imagine wanting to construct a list of all of the arn
values and then joining that list together with commas, for example, but with a dynamic-length list this turns out to be a little beyond what Helm's extension functions provide.
For a sufficiently short list (the couple of items you'd configure in a values.yaml
file would be fine) you can write a recursive function. Remember that Helm templates don't "return values" per se, they output text and include
collects that output text. You could write a recursive template like:
{{- define "cert-arns" -}}
{{- if . -}}
{{- (first .).arn -}}
{{- include "cert-arns.more" (rest .) -}}
{{- end -}}
{{- end -}}
{{- define "cert-arns.more" -}}
{{- if . -}}
,{{- (first .).arn -}}
{{- include "cert-arns.more" (rest .) -}}
{{- end -}}
{{- end -}}
{{- include "cert-arns" (index .Values "ingress.additional_certs") -}}
Note the comma in the fourth-to-last line; that is not a typo. I've indented everything for clarity but also note that the -
inside the curly braces suppresses all of the whitespace.