helmfile icon indicating copy to clipboard operation
helmfile copied to clipboard

Inject release-specific values into values templates?

Open sirianni opened this issue 5 years ago • 11 comments

First off, thanks for this great tool and the responsive and helpful community around it!

We have several use cases where we want to deploy the same chart with two different releases with slightly different values. Since these are third-party charts, we'd like to template the values files themselves to keep them DRY.

Something like this, for example:

- name: envoy-one
  chart: stable/envoy
  values:
  - serviceName: one
  - ./envoy.yaml.gotmpl
- name: envoy-two
  chart: stable/envoy
  values:
  - serviceName: two
  - ./envoy.yaml.gotmpl

And then in envoy.yaml.gotmpl reference the serviceName value:

service:
  name: envoy-{{ .Values.serviceName }}

Since these aren't different environments, using the environments feature doesn't really fit well for this use case. Is there any way to inject release-specific values into the values.yaml.gotmpl file? Or another pattern for achieving this?

sirianni avatar Jun 30 '20 19:06 sirianni

@sirianni Unfortunately there's currently no way to inject release specific values into release-specific values files.

But I'm inclined to add support for it as I've already received so many feature requests on it.

Do you have any idea on how we should differentiate per-helmfile values that can be accessed by {{ .Values }} vs the release-specific values?

mumoshu avatar Jun 30 '20 23:06 mumoshu

Do you have any idea on how we should differentiate per-helmfile values that can be accessed by {{ .Values }} vs the release-specific values?

Should they be differentiated? Or should the values.gotmpl be agnostic to where the values come from (the environment or release)? I'm not too familiar with the history of it, but it seems that the project started out with {{ Environment.Values }} but then switched to just {{ Values }} (maybe for the same reason?). I would think you would want to have the ability for release values to merge with / override environment values so they should be in the same namespace.

My initial thought was that values provided by previous items in the release.values[] array could be available for reference by subsequent values templates in that same array. For example

- name: my-release
  values:
  - foo: 37
  - ./values.yaml.gotmpl

This might not work well though with the current processing model. And some may argue that its too implicit.

A more explicit approach might be to create a new attribute (vars?) in the release:

- name: my-release
  vars:
  - foo: 37
  values:
  - ./values.yaml.gotmpl

With this approach you could still choose to reference those as {{ .Values.foo }} in the gotmpl. Or use {{ .Vars.foo }} if you want to keep this distinct from environment values.

sirianni avatar Jul 01 '20 13:07 sirianni

To add context, we've moved to .Values whilethe adding default values, assuming it's more user-friendly to make values agnostic to where it comes from (environment or default).

Let's say we had a helmfile.yaml like:

# default values
values:
-  foo: default
    bar: default

# environment values
environments:
  prod:
    values:
    - foo: prod

---

releases:
- name: myap
   values:
  - foo: {{ .Values.foo }}
     bar: {{ .Values.bar }}

helmfile -e prod build results in

releases:
- name: myapp
   values:
   - foo: prod
     bar: default

I could have made {{ .Environment.Values.bar }} to render default, instead of {{ .Values.foo }} renders to prod. But then I realized that values can be used without environment values, which makes {{ .Values }} a more general concept.

mumoshu avatar Jul 01 '20 20:07 mumoshu

Merging release-specific values into {{ .Values }} can be a breaking change for people who have been using it to render release-specific values.

vars sounds good, but reminds me of discussions about renaming environment values to environment "variables" so that you won't confuse chart(release) values used for configuring the helm chart with environment values used for helmfile templates.

mumoshu avatar Jul 02 '20 02:07 mumoshu

Would adding {{ .Release.Values }} and making it releases[].values merged into {{ .Values }} provide the wanted feature while keeping backward-compatibility? 🤔

mumoshu avatar Jul 02 '20 02:07 mumoshu

Merging release-specific values into {{ .Values }} can be a breaking change for people who have been using it to render release-specific values.

Good point.

Would adding {{ .Release.Values }} and making it releases[].values merged into {{ .Values }} provide the wanted feature while keeping backward-compatibility?

Not sure exactly what you mean. The values templates would refer to it as {{ .Values.foo }}, but it would go into a new attribute in the helmfile release (named stateValues in my example)? Something like this...?

helmfile.yaml:

values:
- val1: default

releases:
- name: release-1
  values:
  - myapp.values.gotmpl
  stateValues:
  - val1: override
- name: release-2
  values:
  - myapp.values.gotmpl

myapp.values.gotmpl:

service:
  name: myapp-{{ .Values.val1 }}

Would get rendered for release-1 as:

service:
  name: myapp-override

And for release-2 as:

service:
  name: myapp-default

sirianni avatar Jul 02 '20 12:07 sirianni

Thanks for the example! I wasn't clear enough but this is what I mean:

helmfile.yaml:

values:
- val1: default

releases:
- name: release-1
  values:
  - val1: override
  - myapp.values.gotmpl
- name: release-2
  values:
  - val1: override
  - myapp.values.2.gotmpl

myapp.values.gotmpl:

service:
  name: myapp-{{ .Values.val1 }}

myapp.values.2.gotmpl:

service:
  name: myapp-{{ .Release.Values.val1 }}

release-1 gets values of:

service:
  name: default

release-2 gets:

service:
  name: myapp-override

mumoshu avatar Jul 02 '20 20:07 mumoshu

Ah, I see. To preserve compatibility, there are two basic approaches:

  1. Reference the release-specific values with a new name. For example:
{{ .Release.Values }}
  1. Declare the release-specific values with a new name. For example:
releases:
- name: release-1
  values: ...
  stateValues: ...

I tend to prefer option (2) because it seems that the values.gotmpl should not care whether the values come from the global state values, the environment values, or the release-specific values.

sirianni avatar Jul 07 '20 15:07 sirianni

Any update on this issue? gotmpl files are still incompatible with the regular method of referencing release variables usable with a plain .yaml file.

lc-guy avatar Mar 28 '22 14:03 lc-guy