Reputation: 1821
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
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
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