roboll / helmfile

Deploy Kubernetes Helm Charts
MIT License
4.04k stars 566 forks source link

Support `secrets` in nested state #1828

Open yujunz opened 3 years ago

yujunz commented 3 years ago

We have a use case to override some secrets with nested state file like below

helmfiles:
- path: ../../applications/helmfile.yaml
  selectors:
  - name=registry-creds
  values:
  - registry-creds/values.yaml
  secrets:
  - registry-creds/secrets.yaml

But it seems not supported by helmfile

❯ helmfile --selector=name=registry-creds template
in ./helmfile.yaml: failed to read helmfile.yaml: reading document at index 1: yaml: unmarshal errors:
  line 7: field secrets not found in type struct { Path string "yaml:\"path\""; Selectors []string "yaml:\"selectors\""; SelectorsInherited bool "yaml:\"selectorsInherited\""; Environment state.SubhelmfileEnvironmentSpec "yaml:\",inline\"" }
❯ helmfile --version
helmfile version v0.139.0
mumoshu commented 3 years ago

@yujunz Hey! I'm still unsure why on earth many poeple try to do that. Can we just use ref+ URLs in values or just pass the path to the secret file via values?

mumoshu commented 3 years ago

Why are you trying to leverage sub-helmfile in such way? Do you have a big reusable helmfile.yaml that can be reused by carefully passing selectors/values/secrets? I'm not really sure if that's what you really should.

Cant you use reuse the structure by using bases, or just include some repeated snippet of code by using {{ readFile }}, and so on?

yujunz commented 3 years ago

For us, it is mostly for backward compatibility of existing values files. Secrets files are sops encrypted and cannot be used as values file IIUC. Not understanding ref+ URLs, could you elaborate?

The use case is to reuse some base helmfile for different environments. I have tried different ways to implement it but all looks tricky as the selector pattern.

w.r.t. the examples given in https://github.com/roboll/helmfile#environment

I am looking for a kustomize-like overlays to organize values for releases in each environment. What would you recommend? @mumoshu

mumoshu commented 3 years ago

@yujunz Hey! Thanks for confirming.

Not understanding ref+ URLs, could you elaborate?

They are the syntax for remote secrets, which supports all the vals backends.

It seems values under environment are applied to all releases

Nope. Environment values are used to render the whole hemlfile.yaml only. They don't propagate to releases at all.

but we would like to have separate values file for each release.

That's what releases[].values is for. If you really need to pass release values from the parent helmfile, make it configurable in your sub-helmfile.

I am looking for a kustomize-like overlays to organize values for releases in each environment. What would you recommend?

Never use sub-helmfile for that purpose. Use environments to dynamically define release values.

e.g.

environments:
  prod:
    values:
    - someKey: prod
  test:
    values:
    - someKey: test
---

releases:
- name: myapp
  chart: ./somechart
  values:
  - values/{{ .Environment.Name}}/values.yaml
  - someKey: {{ .Values.someKey }}
yujunz commented 3 years ago

I have tested the example and it works as expected.

IIUC, it requires all environments get defined in base helmfile centrally. The challenge we are facing is to organize configurations by environments first then by tools. So it is kind of

base
- terraform
- helmfile
cluster1
- terraform
- helmfile
cluster 2
- terraform
- helmfile

vs

helmfile
- base
- cluster1
- cluster2
terraform
- base
- cluster1 
- cluster2

Either layout has its pros & cons. I am wondering if helmfile can be organized in the former layout.

mumoshu commented 3 years ago

@yujunz I doubt if you need to use environments at all then. How about defining your default helmfile values in base/helmfile/base.yaml and loading it from cluster1/helmfile/helmfile.yaml and cluster2/helmfile/helmfile.yaml?

base/helmfile/base.yaml

values:
- someKey: foo

cluster1/helmfile/helmfile.yaml

bases:
- ../../base/helmfile/base.yaml

---

values:
- anotherKey: {{ .Values.someKey }}bar #=> becomes "foobar"

---

releases:
- name: myapp
  chart: somechart
  values:
  - someKey: {{ .Values.someKey }}
    anotheraKey: {{ .Values.anotherKey }}
yujunz commented 3 years ago

Let me give it a try. I didn't realize the releases in helmfile can be merged and overridden in this way.

parasol-me commented 1 month ago

I have the same problem. I dont think the given solutions are suitable because of sops encryption. My sub helmfiles have sops encrypted values which cant be used...

If i can merge values in sub helmfile why cant i also merge secrets?