roboll / helmfile

Deploy Kubernetes Helm Charts
MIT License
4.05k stars 564 forks source link

QQ - is there support for values variables in hook arguments? #1513

Open mmellin opened 4 years ago

mmellin commented 4 years ago

Thanks for creating such a nice tool!

I would like to understand: 1) Are using values variables (either from the environment or values: key within release) is currently supported within the hook args? 2) If not, is there an alternative for variable arguments in Hooks based on an install environment?

helmfile version v0.125.7

Issue

It looks like values variables from the environments, with the exception of those from a SOPS secret file, are not supported within the hooks arguments. Example:

environments:
  default:
    secrets:
      - ../some/other/charts/secrets.yaml

releases:
  - name: mychart
    namespace: test
    chart:  charts/mychart
    values:
      - generic:
           val: foo
    hooks:
      - events: ["postsync"]
        command: "./bin/hello-world"
        args: [
          "--arg1", "{{ .Values.super_secret_pwd }}",   # <<< From 'secrets.yaml'
          "--arg2", "{{ .Values.generic.val }}",         

If I run the above today I get an error related to the secret, not the value:

$ helmfile lint
in ./helmfile.yaml: error during helmfile.yaml.part.0 parsing: template: stringTemplate:47:32: executing "stringTemplate" at <.Values.super_secret_pwd>: map has no entry for key "super_secret_pwd"

However, if I remove {{ .Values.generic.val }} the lint passes successfully.

dsuievalov commented 4 years ago

@mmellin values that we pass to the release can not be used for templating since they are passed to helm charts in the same way as you run helm lint --values=<file-with-your-vars>. Which is why you can not use "{{ .Values.generic.val }}" in hooks if it is not defined in environments values. As for the main issue with secret value .Values.super_secret_pwd - tried to reproduce the behavior but it looks like it is working fine for me at least:

helmfile.yaml:

---
repositories:
  - name: stable
    url: https://kubernetes-charts.storage.googleapis.com

environments:
  default:
    secrets:
      - secrets.yaml

---
releases:
  - name: nginx-ingress
    namespace: test
    chart: stable/nginx-ingress
    hooks:
      - events: ["prepare"]
        showlogs: true
        command: "/bin/echo"
        args: ["test value: {{ .Values.test }}"]
    values:
      - generic:
          val: foo

secrets.yaml:

test: ENC[AES256_GCM,data:...,type:int]
sops:
    kms: []
    gcp_kms:
    -   resource_id: ...
        created_at: '2020-10-05T08:30:05Z'
        enc: ...
    azure_kv: []
    hc_vault: []
    lastmodified: '2020-10-05T08:30:07Z'
    mac: ENC[AES256_GCM,data:...,type:str]
    pgp: []
    unencrypted_suffix: _unencrypted
    version: 3.6.1
$ helmfile -n test-build-00 lint
Decrypting secret /test/secrets.yaml
Decrypting /test/secrets.yaml

Adding repo stable https://kubernetes-charts.storage.googleapis.com
"stable" has been added to your repositories

helmfile.yaml: basePath=.

hook[prepare] logs | test value: 1
hook[prepare] logs |
Fetching stable/nginx-ingress
Linting release=nginx-ingress, chart=/var/folders/88/094f07ks7rs4tkcmj5rnf06m0000gp/T/596919152/test/nginx-ingress/stable/nginx-ingress/latest/nginx-ingress
==> Linting /var/folders/88/094f07ks7rs4tkcmj5rnf06m0000gp/T/596919152/test/nginx-ingress/stable/nginx-ingress/latest/nginx-ingress

1 chart(s) linted, 0 chart(s) failed

The good way to check if the secrets is actually picked up is to run helmfile build --embed-values which will print the helmfile with substituted vars/secrets:

$ helmfile build --embed-values
Decrypting secret /test/secrets.yaml
Decrypting /test/secrets.yaml

helmfile.yaml: basePath=.

hook[prepare] logs | test value: 1
hook[prepare] logs |
---
#  Source: helmfile.yaml

filepath: helmfile.yaml
helmBinary: helm
environments:
  default:
    secrets:
    - secrets.yaml
repositories:
- name: stable
  url: https://kubernetes-charts.storage.googleapis.com
releases:
- chart: stable/nginx-ingress
  hooks:
  - name: ""
    events:
    - prepare
    command: /bin/echo
    args:
    - 'test value: 1'
    showlogs: true
  name: nginx-ingress
  namespace: test
  values:
  - generic:
      val: foo
  forceNamespace: ""
templates: {}
missingFileHandler: ""