Helm Secret Juggling
This solution requires a values file with the following schema. Notice how each component is in components
. The best part of this is that if there is no secrets
property in the component, it will skip the secrets template.
If no value is provided by setting it via the command line and it has a value already set, it will use the current value in the secret.
All secrets will be initialized with the value of initial
unless they are specifically provided on install
or upgrade
like so.
helm upgrade juggle ./chart_directory -n juggle \
--set components.second.secrets.SUPER_SECRET="string"
## values.yaml ##
components:
first:
name: first component
second:
name: second component
secrets:
SUPER_SECRET: null
ANOTHER_SECRET: null
## secrets.yaml ##
{{- range $system, $settings := .Values.components -}}
{{ if $settings.secrets }}
{{ include "system.secrets.component" (dict "component" $settings "values" $.Values "release" $.Release) }}
{{- end }}
{{- end }}
## _secrets.tpl ##
{{/*
Secret initializer and data maintainer
This helper will initialize the secret data with "initial" value if the secret is not found in the secret object.
IF the secret is found in the secret object, it will use the set value from the secret object thereby maintaining the secret data.
*/}}
{{- define "helper.secrets" -}}
{{- $secretObj := (lookup "v1" "Secret" .release.Namespace .component.name) | default dict }}
{{- range $key, $value := .component.secrets }}
{{- if empty $value -}}
{{- $secretData := (get $secretObj "data") | default dict }}
{{- $secret := (get $secretData $key) | default ("initial" | b64enc) }}
{{ $key }}: {{ $secret | quote }}
{{- else }}
{{ $key }}: {{ $value | b64enc | quote }}
{{- end -}}
{{- end }}
{{- end -}}
{{- define "system.secrets.component" }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .component.name }}
labels:
{{ include "helper.metaLabels" . | indent 4 }}
type: Opaque
data:
{{ include "helper.secrets" . | indent 2 }}
{{- end }}
Troubleshooting
In order to really test this during a ` Dry Run` you need to make sure you tweak your option so helm has access to the server data at run time.
--dry-run=server