helmfile
helmfile copied to clipboard
Inject release-specific values into values templates?
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 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?
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.
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.
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.
Would adding {{ .Release.Values }} and making it releases[].values merged into {{ .Values }} provide the wanted feature while keeping backward-compatibility? 🤔
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 itreleases[].valuesmerged 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
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
Ah, I see. To preserve compatibility, there are two basic approaches:
- Reference the release-specific values with a new name. For example:
{{ .Release.Values }}
- 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.
Any update on this issue? gotmpl files are still incompatible with the regular method of referencing release variables usable with a plain .yaml file.