Open Arabus opened 4 years ago
@Arabus Hey! Thanks for reporting.
I admit this is confusing, but this is working as intended.
--state-values-set
and --state-values-file
is basically a way to "prepend" a set of state values to be used by "rendering" helmfile state values. It works like that because the target use-case of it is to support people trying to "feed" helmfile.yaml template to dynamically produce state values from the state values passed via command-line flags.
Internally, your second example translates to something like below:
values:
second:
enabled: true
---
environments:
default:
values:
- second:
enabled: false
releases:
- name: one
namespace: first
chart: stable/wordpress
- name: two
namespace: second
chart: stable/wordpress
condition: second.enabled
Before evaluating second.enabled
, Helmfile merges {"second": {"enabled": true}}
and {"second": {"enabled": false}}
and produces `{"second":{"enabled":false}}" as the latter wins.
A workaround that you can use today would be to explicitly program it like:
environments:
default:
values:
- second:
enabled: {{ get "second.enabled" .Values false }}
so that your second example internally translates to:
# Again, this is coming from `--state-values-file`
values:
second:
enabled: true
---
environments:
default:
values:
- second:
enabled: {{ get "second.enabled" .Values false }}
I believe this defeats your (possible) original motivation to use --state-values-set
to avoid templates just for defaulting. But unfortunately this is how it works today.
I'm not satisfied with this solution. So my suggestion is to add Helmfile any way to "append" or "override"(which term do you prefer, btw?) state values via command-line.
Maybe we'd better deprecate --state-values-(set|file)
as confusing, rename it to --prepend-values
, and later add --append-values
for what you might have wanted?
Any input is much appreciated. Thanks anyway for trying Helmfile!
To be extra clear, internally Helmfile produces the below for your first example:
# The original `values` defined in your helmfile.yaml
values:
- second:
enabled: false
---
# From your --state-values-file flag
values:
second:
enabled: true
---
releases:
- name: one
namespace: first
chart: stable/wordpress
- name: two
namespace: second
chart: stable/wordpress
condition: second.enabled
Please note that --state-values-file
is inserted between your original values
and releases
in this case, which is why it works.
Hi!
I'm having a similar problem and the examples you have here haven't really cleared them up for me. The {{ get "second.enabled" .Values false}}
that you list actually crashes for me.
In my case, I want to have a helmfile that has a small set of releases that are enabled by default and then a larger set of optional releases that are disabled by default but can be turned on by passing information when helmfile apply/sync
are called.
Unfortunately, it looks like conditions can only be satisfied by passing a --state-values-file (I can't get --state-values-set to work at all) and if you don't supply one at all the entire command crashes with the error:
panic: interface conversion: interface {} is nil, not map[string]interface {}
goroutine 1 [running]:
github.com/roboll/helmfile/pkg/state.markExcludedReleases(0xc000365b00, 0x1, 0x1, 0xc0007007a0, 0x1, 0x1, 0x0, 0xc0001bf4d0, 0x0, 0x0, ...)
/home/circleci/workspace/helmfile/pkg/state/state.go:1832 +0xb5a
However, I can't seem to find a combination of passing values either external to a helm file or internal to it that let something like
releases:
- name: foo
chart: foo
version: 1.0.0
condition: foo.enabled
pick up a value for foo.enabled unless I set it through --state-values-file. That is, the code just dies instantly if it can't find a value for the condition and there's no way to give it a default value for foo.enabled.
I think either the prepend or append switches you propose are still pretty confusing. In most systems I've encountered, the order of precedence is anything set on the command-line wins, then anything in a configuration file, then anything specified in the code itself.
I also tried to use selectors to pick which things I want to install, which seems to work better but you have specify the selectors for everything you want or you get nothing. I can't have selectors that are turned off by default and then re-enable them on the command line.
There seems to be a lot of flexibility in what helmfile allows but the order of precedence is pretty hard for me to understand.. I might suggest looking at how something like ansible is doing this as an example of a system that seems more predicable.
I ran into this as well while working on a CD pipeline. As a workaround for now I am doing the following for a microservice deployment:
# in helmfile.yaml
values:
- image:
tag: '{{ requiredEnv "IMAGE_TAG" }}'
IMAGE_TAG=v1.2.3 helmfile -f helmfile.yaml diff
I'd be interested in the proper way to use --state-values-set
though. I assumed that this would be like the following:
helmfile -f helmfile.yaml --state-values-set .image.tag=v1.2.3 diff # this did not work for me.
I'm not satisfied with this solution. So my suggestion is to add Helmfile any way to "append" or "override"(which term do you prefer, btw?) state values via command-line.
I prefer override
to append
. I expect CLI values to have highest priority.
In general I expect CLIs to support an option priority like: explicit CLI values > ENVIRONMENT > user config > specific config > defaults.
Maybe we'd better deprecate --state-values-(set|file) as confusing, rename it to --prepend-values, and later add --append-values for what you might have wanted?
I agree with deprecation and also with OP's request that the usage and interaction and merge behavior be documented. --state-values-set
does not behave similarly to helm's --set
and this is surprising and unexpected.
Use Case: I want to temporarily disable a helmfile app temporarily. In my case, while making some changes to the underlying PV/PVC that need to be atomic relative to the app.
When trying to enable/disable releases via the environment clause in helmfile I came about the issue that overriding those values via CLI seems to be impossible. The apparent merge behaviour seems to be
helmfile.yaml values section <- helmfile cli --state-values-file|--state-values-set <- helmfile.yaml environment values section
I'd expect otherwise i.e., the CLI overriding everything but even if this is not intended I'd rather like a documentation snippet stating the merge behaviour of those sections/options
Testcases
This one works when overriding on the CLI (albeit I need to provide the boolean via a pseudofile)
This one doesn't, in fact the second release stays disabled
Relevant Metadata
Helmfile version
Helm version & Plugins
go version
mac os version