Ana Franco
Ana Franco

Reputation: 1821

Create file for secret in pre-install hook

I have a helm chart and I need to create a file before installing all my resources to be able to store it in a secret. I have been reading about Helm Hooks and I think I can create a hook, insert my script files, run my script and generate the file I need, where I'm lost is on how can I get my file out of the pod and insert it as a secret.

These are my hooks:

Secret hook for the scripts:

apiVersion: v1
kind: Secret
metadata:
  name: hlf-genesis-block
  namespace: hlf
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "0"
    "helm.sh/hook-delete-policy": hook-succeeded
type: Opaque
data:
  createfile.sh: |-
    {{ .Files.Get "scripts/createfile.sh" | b64enc }}

Job Hook:

apiVersion: batch/v1
kind: Job
metadata:
  name: "post-install-hook"
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      volumes:
      - name: scripts
        secret:
          secretName: scripts
      restartPolicy: Never
      containers:
      - name: channel-config
        image: "ubuntu:20.04"
        command: ["bash", "-c", "
                domainname=\"{{ .Values.domainName }}\"
                ./createfile.sh \"$domainname\"
              "]
        volumeMounts:
        - mountPath: /home/
          name: scripts
          readOnly: true

Final secret file:

apiVersion: v1
kind: Secret
metadata:
  name: hlf-genesis-block
  namespace: hlf
type: Opaque
data:
  secret.txt: |-
    {{ .Files.Get "generatedfile.txt" | b64enc }}

I was thinking maybe like assigning a variable using something like this inside the job:

{{ $secret := echo generatedfile.txt }}

But I haven't found a function for it, or mapping a volume temporarily, but even that way I haven't been able to figure out how to take out the secret from my job or the temporal storage, as the .Files.Get works from where the kubectl is running...

Or maybe running kubectl from inside the job to create the secret? although then I wont be able to delete the secret on uninstall.

Any ideas would be great.

Thanks

EDIT:

Is it possible to modify the secret value by modifiing the mapped secret volume? I'm going to try that.

Upvotes: 2

Views: 3265

Answers (2)

Ana Franco
Ana Franco

Reputation: 1821

Using storages its a good solution, but for the sake of completion this is the way I did it using secrets:

I created the final secret with a phony value

apiVersion: v1
kind: Secret
metadata:
  name: hlf-genesis-block
  namespace: hlf
type: Opaque
data:
  secret.txt: {{ "empty" | b64enc }}

Then I created a role and a rolebinging to be able to modify the secret from the job

Role:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: update-secrets
  namespace: hlf
rules:
  - apiGroups:
      - ""
    resources:
      - secrets
    verbs:
      - get
      - patch

RoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: update-secrets
  namespace: hlf
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: update-secrets
subjects:
  - kind: ServiceAccount
    name: default
    namespace: hlf

Finally I didn't use a hook as the job runs much faster than my deployments that need to map some persistent volumes and changed the command like this:

apiVersion: batch/v1
kind: Job
metadata:
  name: "genesis-job"
spec:
  template:
    spec:
      volumes:
      - name: scripts
        secret:
          secretName: scripts
      restartPolicy: Never
      containers:
      - name: channel-config
        image: "myrepo/fabric-tools-with-k8s"
        command: ["bash", "-c", "./createfile.sh \"{{ .Values.domainName }}\" && cat genesis.block | base64 > encoded.block  && genesis=$(cat encoded.block | tr -d '\n') && patch="[{\"op\":\"replace\",\"path\":\"/data/genesis.block\",\"value\":\"$genesis\"}]" && kubectl patch secret hlf-genesis-block --type=json -p="$patch""]
        volumeMounts:
        - mountPath: /home/
          name: scripts
          readOnly: true

Upvotes: 2

Sagar Velankar
Sagar Velankar

Reputation: 855

I recommend going over https://github.com/helm/charts/tree/master/stable and https://github.com/bitnami/charts to reuse existing solution

Helm Template https://github.com/bitnami/charts/blob/master/bitnami/rabbitmq/templates/secrets.yaml uses randAlphaNum template function https://helm.sh/docs/chart_template_guide/function_list/#randalphanum-randalpha-randnumeric-and-randascii to generate the secret.

The problem with randAlphaNum generating new secret every time helm install/upgrade command is run is solved by https://github.com/helm/helm/issues/3053#issuecomment-782837107 using lookup template function https://helm.sh/docs/chart_template_guide/functions_and_pipelines/#using-the-lookup-function. Below code is copied from https://github.com/helm/helm/issues/3053#issuecomment-782837107

apiVersion: v1
kind: Secret
metadata:
  name: foobar-secret
type: Opaque
{{- $previous := lookup "v1" "Secret" .Release.Namespace "foobar-secret" }}
data:
  {{- if $previous }}
  foobarPassword: {{ $previous.data.foobarPassword }}
  {{- else if .Values.foobarPassword }}
  foobarPassword: {{ .Values.foobarPassword | b64enc | quote }}
  {{- else }}
  foobarPassword: {{ randAlphaNum 40 | b64enc | quote }}
  {{- end }}

EDIT :

Init Demo Pod Definiton : https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-initialization/

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: channel-config
      mountPath: /run/channel-config
  # These containers are run during pod initialization
  initContainers:
  - name: channel-config
    image: "ubuntu:20.04"
    command: ["bash", "-c", "cd /run/channel-config && ./createfile.sh \"{{ .Values.domainName }}\""]
    volumeMounts:
    - name: channel-config
      mountPath: "/run/channel-config"
  dnsPolicy: Default
  volumes:
  - name: channel-config
    emptyDir: {}

Upvotes: 2

Related Questions