-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Helm should preform deep merge on multiple values files #3486
Comments
I think i found the issue and ill try to open a PR |
If this is implemented, it should be optional, i. e. the merge mode should be specified as a command-line flag. Anything else would be a breaking change and, I think, in most cases not desirable. The problem is that you would not be able to override defaults for lists. Here's an example: https://github.com/kubernetes/charts/blob/5453fc144f6f9d722c6bb433790f90d7943a4fc3/stable/docker-registry/values.yaml#L19 For those coming from the Java world, here's how Maven solves this for plugin configurations: https://blog.sonatype.com/2011/01/maven-how-to-merging-plugin-configuration-in-complex-projects/ |
Sorry you did not get the expected results and I agree that its a frustrating limitation. If you are interested in contributing a feature please create a proposal spelling out the implementation which should include a flag as @unguiculus suggested. |
Thanks @unguiculus! I see now how this would be considered a breaking change.
Are you saying you wouldn't be able to override an entire list (for example overriding a list of 3 items with a list of 1 item)? What I'm proposing would allow you to override individual defaulted items in a list. Giving you more control. I guess Im not seeing why merging maps is desirable and merging lists is not desirable, except that at the current time some projects expect a certain behavior while others expect another. @jascott1 Thanks, I will definitely think about the proposal with my team, but what I really needed was a quick fix that I thought could be resolved with a quick PR. At this time we need to focus on our immediate problem. |
Was this functionality ever added? |
I also see this as a limitation, especially for projects like prometheus where the whole prometheus configuration is defined in values file. Not being able to merge on sub-keys, I have to copy almost the same config per environment with is a huge repetition of code. |
#4806 might be relevant, in which case this should exist for 2.12.0 (not yet released; try out the canary release to test). |
Just ran into this and I'm confused as to why this was closed. As @mlushpenko states this seems like a pretty major limitation for managing any reasonably sized deployment. In our case we would like to be able to combine affinity rules from multiple levels -- providing a default set of rules in the base chart that can be augmented when deployed. However, as it stands we have to repeat the default affinity rules in every values override file. Not even close to DRY. This is compounded by the fact that it doesn't seem possible to specify default values that will be based on things like the release name which aren't known until the deployment is performed (granted that's unrelated, but it means that overriding affinity essentially has to be done on every deployment). |
@bacongobbler I have and I don't see how it applies. AFAICT, it only deals with updates made during upgrade of an already deployed chart and ensuring that existing values aren't clobbered by new ones. Certainly related, but I don't see how it helps avoid the need to repeat information when combining values files during the initial install. |
We'd really like this feature as well. We have a hierarchy of values files (eg: base.yaml <- qa.yaml) which are passed to helm via |
I could also use this |
I know this issue is closed, but as a point of reference for those looking here and thinking of resolving the issue I'll supply a comparison with chef. There this issue is resolved by a fixed set of priorities for values (which they call attributes). Arrays set with the same priority will be merged, while a higher priority value will replace lower priority values. https://docs.chef.io/attributes.html#about-deep-merge If implementing something similar in helm I think it would make sense to introduce new versions of --set and --values, say, --overrideSet and --overrideValues for high priority values. As for setting values in a chart another file called, say, overrideValues.yaml could be allowed which sets values at a higher priority than in the values.yaml file. |
We could also use this. +1 |
I'm a bit confused. The open end of this thread gave me the impression that this merging thing is still missing in helm. After trying it out (we do helm upgrade ... -f basic.yaml -f profile_extends_basic.yaml), it seems to work correctly. At least for me the #4806 seems to have nailed it. |
@janotav The #4806 addressed deep merge for the upgrade scenario. This issue was about merging values during normal install. |
Yes. This is feature is needed. Another use case is to specify/merge/override a subset of environment variables across different deployment environments. |
This continues to be a problem with helm 2.x, does anyone know if helm 3.x have a solution for (optionally) merging arrays during install? |
I too would love to see this functionality! |
For the folks here who need to modify the list of environment variables you're passing into your deployment template, the solution is to define the vars and defaults as a values.yaml:
values-production.yaml:
deployment.yaml:
Rendered, using values-production:
|
@tarrall Can you supply the helm commands you used as well for the merge? I'm trying to have my helm chart contain default values which are put into a configmap, then have a environment-specific file that I merge into the defaults, but it's overriding instead. I'm using the Does it matter if you're using helm2 or helm3 btw? |
puppet with hiera also manages this, giving options of which kind of merge do you want. I am also repeating code because I have several pods that need to mount the exact same file from a configmap and another specific for each pod. The common should be declared in an upper hierarchy and then give the option to merge the values below |
@bacongobbler isn't possible to reopen this issue taking in consideration that #4806 doesn't solves this problem because it does deep merge in maps and in an upgrade process. What @connormckelvey mentioned was the ability to do deep merge in arrays. This kind of deep merge should work for install and upgrade situations. |
I'm surprised helm has no solution for this. The workaround @tarrall suggested doesn't scale well into complex lists involving many keys & sub-lists. @connormckelvey please could you reopen? |
I am using the following script as a workaround: import yaml fileA = “tmp.yaml" with open(fileA,'r+') as f: with open(fileB,'r+') as f: result = always_merger.merge(fileAdictionary, fileBdictionary) |
An all or nothing approach like that is very dangerous when having big and/or many values files. Another problem with this is that you then can't control the behaviour in a chart. I prefer the solution I outlined in #3486 (comment) |
I noticed recently that using Helm version: |
In fact, only value.yaml before
value.yaml after
deployment.yaml before
deployment.yaml after
This will support the merge of If you want to delete a configuration
|
@tarrall 's solution didn't work for map-type values, such as
|
@alpozcan can you give an example with |
Note for people from the future that stumble on this: |
Posting here in case it is useful for someone. Iterating upon what others have shared here, I did the following to get it working for
|
Supporting deep merge is only possible with dictionaries. This breaks ordering and hence dependent environment variables. Since I was working on this issue for a while, I finally decided to write a bit more about it: An Advanced API for Environment Variables in Helm Charts and provide a library chart to solve this issue. |
@connormckelvey could you please reopen this issue. |
does this work in nested dicts:
and
I'm ending up with
omitting the second env |
please reopen @monotek. I don't think a reasonable solution has been provided to figure this out. For context, I found this via a search as I have 2 files the define the same pathway,
What I expect is that I should be able to pass in these files and have the values merged for a proper output, but what I see for the
|
@clear-ryan |
I am seeing the expected behavior on base.yaml:
override.yaml:
override2.yaml:
command:
This is exactly the expected behavior. Appending lists to each other is not standard behavior for a "deep merge" on a dict (this functionality exists in many languages, not only helm). There are many reasons specified in this thread and elsewhere online for why this behavior is not desirable. It is inconvenient for some cases but causes intractable problems in many other cases. It's also inconsistent with the behavior of other data types. For example, would you expect string values to be concatenated rather than replaced? I don't think that would be logical either. This issue should not be reopened because it already works as expected. |
It looks like #1620 was supposed to provide this functionality but I am seeing that a list in the last specified values file completely override the list from the previous file
I have 2 additional values files foo.yaml, and bar.yaml as follows:
foo.yaml
bar.yaml
cronjob.yaml template
When running
helm install --dry-run --debug ./cronjob -f values/foo.yaml,values/bar.yaml
or when runninghelm install --dry-run --debug ./cronjob -f values/foo.yaml -f values/bar.yaml
It outputs the following:
actual output
I expect the env lists from values.yaml, foo.yaml, and bar.yaml to have been merged resulting in the following:
expected output
The text was updated successfully, but these errors were encountered: