12

On my helm chart I have a job with the pre-install hook where I need to use a property from my secrets. However when I try to install my helm chart I get the following error on my pre-install job:

Error: secret "SecretsFileName" not found

Secrets aren't created before the pods execution? What's the problem here? How can I solve this?

Notes:

  • I want to use secrets to have the properties encrypted. I don't want to use the decrypted value directly on my pod;
  • I already read Helm install in certain order but I still not understanding the reason of this error;
  • I already tried to use "helm.sh/hook": pre-install,post-delete and "helm.sh/hook-weight": "1" on secrets, and "helm.sh/hook-weight": "2" on my pod but the problem remains.

My pre-install job:

apiVersion: batch/v1
kind: Job
metadata:
  name: "MyPodName"
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
  #some more code
spec:
  template:
    #some more code
    spec:
      dnsPolicy: {{ .Values.specPolicy.dnsPolicy }}
      restartPolicy: {{ .Values.specPolicy.restartPolicy }}
      volumes:
        - name: {{ .Values.volume.name }}
          persistentVolumeClaim:
            claimName: {{ .Values.volume.claimName }}
      securityContext:
        {{- toYaml .Values.securityContext | nindent 8 }}
      containers:
        - name: "MyContainerName"
          #some more code
          env:
            - name: SECRET_TO_USE
              valueFrom:
                secretKeyRef:
                  name: SecretsFileName
                  key: PROP_FROM_SCRETS
          #some more code

My secrets file:

apiVersion: v1
kind: Secret
metadata:
  name: "SecretsFileName"
  labels:
    app: "MyAppName"
    #some more code
type: Opaque
data:
    PROP_FROM_SCRETS: eHB0bw==
Ninita
  • 1,209
  • 2
  • 19
  • 45

2 Answers2

13

While Helm hooks are typically Jobs, there's no requirement that they are, and Helm doesn't do any analysis on the contents of a hook object to see what else it might depend on. If you read through the installation sequence described there, it is (7) install things tagged as hooks, (8) wait for those to be ready, then (9) install everything else; it waits for the Job to finish before it installs the Secret it depends on.

The first answer, then, is that you also need to tag your Secret as a hook for it to be installed during the pre-install phase, with a modified weight so that it gets installed before the main Job (smaller weight numbers happen sooner):

apiVersion: v1
kind: Secret
annotations:
  "helm.sh/hook": pre-install
  "helm.sh/hook-weight": "-5"

The next question is when this Secret gets deleted. The documentation notes that helm uninstall won't delete hook resources; you need to add a separate helm.sh/hook-delete-policy annotation, or else it will stick around until the next time the hook is scheduled to be run. This reads to me as saying that if you modify the Secret (or the values that make it up) and upgrade (not delete and reinstall) the chart, the Secret won't get updated.

I'd probably just create two copies of the Secret, one that's useful at pre-install time and one that's useful for the primary chart lifecycle. You could create a template to render the Secret body and then call that twice:

{{- define "secret.content" -}}
type: Opaque
data:
    PROP_FROM_SCRETS: eHB0bw==
{{- end -}}
---
apiVersion: v1
kind: Secret
metadata:
  name: "SecretsFileName"
  labels:
    app: "MyAppName"
{{ include "secret.content" . }}
---
apiVersion: v1
kind: Secret
metadata:
  name: "SecretsFileName-preinst"
  labels:
    app: "MyAppName"
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
{{ include "secret.content" . }}
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Is there an explanation though as to why the job/helm/k8s tends to delete the secret as well as the job? I'm currently facing this issue and the extra secret seems to be a hack even though would work. – John Sep 21 '20 at 16:27
  • 1
    This is very nice, I have adopted the template approach! One thing I want to flag though - and it might be that it's only an issue with newer K8 versions - is that you need to put the hook weight into quotes as it's required to be given as a string. (https://helm.sh/docs/topics/charts_hooks/#writing-a-hook) – robbash Apr 12 '21 at 12:55
  • Thanks @robbash, I've fixed that. (Syntactically annotation keys and values always need to be strings and it shouldn't be specific to Kubernetes or Helm versions.) – David Maze Apr 12 '21 at 13:59
  • I'm a bit confused by the `"helm.sh/hook-delete-policy": hook-succeeded` part. If I'm installing a secret, don't I want it to remain after installing it? For me, the secret I was trying to install did get installed first like I wanted, but then it got automatically deleted. I had to add `helm.sh/resource-policy: keep`. This is helm `3.4.1`. – slevin May 28 '21 at 17:48
0

According to the docs:

pre-install: Executes after templates are rendered, but before any resources are created in Kubernetes

prometherion
  • 2,119
  • 11
  • 22
  • I already read that. And `Secret` is a resource? And what is the solution? Everyone use secrets on pods... – Ninita Dec 20 '19 at 10:59