helmfile
helmfile copied to clipboard
"prepare" hook is not executed before apply command
I have a use case where I need to avoid hardcoding the default serviceaccount token. This value is declared in values.yaml and I am referring it in my release. My logic is to execute a script via a Prepare hook however I understand that even this hook is triggered before the release, the apply command still saves a state first before where the kubernetesAuthSecret is still XXXXXX, which is before the script execution. Once the release is installed, I can check the values.yaml and I can see that the new token updated but I have the XXXXXX in my cluster. Steps to reproduce:
values:
- environment: poc
- namespace: myns
- kubernetesAuthSecret: XXXXXX
- name: "{{ .Values.releaseName }}-cert"
chart: incubator/raw
version: 0.2.5
namespace: "{{ .Values.namespace }}"
hooks:
- events: ["prepare"]
showlogs: true
command: "../../../scripts/getKubernetesAuthSecret.sh"
args: ["{{ .Values.namespace }}","{{ .Environment.Name }}"]`
#!/bin/bash
ns=$1
env=$2
kubectl get namespace $ns 2> /dev/null
if [ "$?" -eq 0 ]
then
token=$(kubectl get serviceaccounts default -n $ns -ojson | jq -r '.secrets | .[0].name')
sed -i "/$env/,/kubernetesAuthSecret/s/kubernetesAuthSecret:.*/kubernetesAuthSecret: "$token"/" ./helmfile.yaml
``
else
echo "$ns doesn't exist, consider changing or creating it."
fi
command:
helmfile -e poc --debug -i -f helmfile.yaml apply
@AbbasHallal Hey! Would you mind completing your example so that I can reproduce it?
Two things:
- You seem to be running
sed
against./helmfile.yaml
, but it should bevalues.yaml
if I took your description ofThis value is declared in values.yaml and I am referring it in my release.
as the truth? - Your release is missing
values
section at all. should't it be something like the below?
- name: "{{ .Values.releaseName }}-cert"
chart: incubator/raw
version: 0.2.5
namespace: "{{ .Values.namespace }}"
hooks:
- events: ["prepare"]
showlogs: true
command: "../../../scripts/getKubernetesAuthSecret.sh"
args: ["{{ .Values.namespace }}","{{ .Environment.Name }}"]`
# Didn't you miss this?
values:
- values.yaml
Ok will paste for you my exact config so that you will be able to reproduce because there's something missing and it created confusion helmfile.yaml:
environments:
poc:
values:
- environment: poc
- namespace: myns
- releaseName: myrelease
- kubernetesAuthSecret: xxxxx
secrets:
- secrets.yaml
{{ tpl (readFile "../../bases/cert.yaml") . }}
script:
#!/bin/bash
ns=$1
env=$2
kubectl get namespace $ns 2> /dev/null
if [ "$?" -eq 0 ]
then
token=$(oc get serviceaccounts default -n $ns -ojson | jq -r '.secrets | .[0].name')
sed -i "/$env/,/kubernetesAuthSecret/s/kubernetesAuthSecret:.*/kubernetesAuthSecret: "$token"/" ./helmfile.yaml
else
echo "$ns doesn't exist, consider changing or creating it."
fi
cert.yaml:
- name: "{{ .Values.releaseName }}-cert"
chart: incubator/raw
version: 0.2.5
namespace: "{{ .Values.namespace }}"
hooks:
- events: ["presync"]
showlogs: true
command: "../../../scripts/getKubernetesAuthSecret.sh"
args: ["{{ .Values.namespace }}","{{ .Environment.Name }}"]
labels:
app: cert
values:
- resources:
- kind: Secret
apiVersion: v1
metadata:
name: secret
data:
kubernetesAuthSecret: {{ .Values.kubernetesAuthSecret | b64enc }}
type: Opaque
So in the above scenario, I want to change kubernetesAuthSecret
from xxxxx
which is a random variable and varies among different namespaces to the value of the current namespace where the release is installed. It's not working through the prepare hook. I am getting the xxxx as value in the secret.Lets say the release was installed and I checked the helmfile.yaml again, the kubernetesAuthSecret
will be default-token-fdwcc
. As far as my understanding, the apply command is saving an initial state and ignoring what is called after it.
@mumoshu Hello, Were my description clear so you can reproduce it?
@AbbasHallal Thanks. But I'm pretty confused! Your getKubernetesAuthSecret
script seems to be trying to modify the helmfile.yaml
that called it, and you want helmfile to magically reload the helmfile.yaml
after the hook is called, right?
Helmfile won't work that way..
@mumoshu I thought the prepare hook would be able to modify values is helmfile.yaml but seems not logical in this way I am doing it. You're right, trying to edit a helmfile by a hook that was created by it.
@AbbasHallal prepare
hook was originally added to dynamically generate or modify the chart. I have not tried myself but you could exploit it to dynamically generate a chart values file, I guess.
releases:
- name: ...
values:
- generateme.yaml
and use the hook to update the generateme.yaml.