Apr 3rd, 2022
Every now and then you’ll need to use the
--reuse-values flags when running
helm upgrade. Let’s dive into how they actually work, and also look at a gotcha when the values of a chart have changed in-between upgrades.
Here are the different scenarios visualized in a table:
To learn about them in more depth, continue reading…
--reuse-valuesand schema change
The point of Helm is that you can customize parameters of a chart (in Helm lingo, parameters are called just values).
For example, as part of the loki-stack chart you can enable and disable components of the stack by setting a value via
helm install example-loki grafana/loki-stack --set grafana.enabled=true
The same applies for upgrading an existing release. You can change a value and the chart is expected to reconfigure itself according to your customization:
helm upgrade example-loki grafana/loki-stack --set grafana.enabled=false
Notice that the chart name had to be specified even though you just wanted to update the values using the same chart that was installed already? That is because the upgrade-command is also able to upgrade the release to a different version of the chart (technically also to any other chart, although that does not sound like a common usecase). A common workflow is to update charts from remote repos, and then upgrade releases to the latest version:
helm repo update helm upgrade ...
It’s also possible to set a specific version of a chart to upgrade to:
helm upgrade example-loki grafana/loki-stack --version 1.2.3
The fact that you can reconfigure and update charts is the whole purpose of Helm. I’m sure you are familiar with all of the above if you’ve used Helm before.
But the way that configuration changes are merged together may catch you off guard. The upgrade-command contains some internal logic, which can seem inconsistent. It may get even more confusing when the values of the chart you’re upgrading to have changed since the original chart version. I personally had to actually test out the different variations one-by-one to understand all of it fully.
The first potential surprise is that the difference in merging behaviour is actually determined by this: are you also setting values during the upgrade?
If you are, Helm implicitly uses a “reset values” strategy.
If you are not, Helm implicitly uses a “reuse values” strategy.
Both of these strategies can also be enforced via CLI flags, which we’ll cover below.
Finally, there is also an important gotcha to know related to reusing values when the values schema in the chart has changed. I will also cover that in the end.
Let’s go through everything in the form of examples.
When you simply upgrade a chart to a new version, your previous values will stay in effect:
This is the “reuse values” strategy I mentioned before.
But if you also set some values during the upgrade, your previous values actually get wiped out!
This is the “reset values” strategy I mentioned before. Values are reset to the default values of the new chart version, and any new values you’ve specified on the CLI are merged on top of that.
This can be quite surprising! You need to be careful not to accidentally undo some customization.
You can control which strategy to use via CLI flags.
If you are not setting new values, but want to reset to the chart defaults, you can do so via
And in the opposite case, if you are setting new values but want to merge them to previous values, you can use
Well, this works as long as the values schema hasn’t changed in the new chart version. So, for the most part, all clear! But what if the schema has changed…
Sometimes the updated chart has changes in its
values.yaml. For example, some section may have been added or an existing one changed a bit. You would expect these changes to be merged into your new release, right?
And so they are! But only if you’re not using
--reuse-values. Which is confusing, because it makes the flag behave differently from our first example which works almost like
--reuse-values but also merges in changes from the chart.
So, to clarify… when you do a simple upgrade without setting any values or flags, the updated
values.yaml from the new chart version is merged to your release as expected:
But when you want to also update one of the previously set values at the same time, you will naturally use
--set, right? Well, in this case
--reuse-values has an unexpected effect. It causes Helm to quite literally “reuse values” from your previous release as the base, disregarding any changes that may have happened in the new chart version:
This is not the logic you expected, right? You did explicitly ask to reuse values, sure, but why would you expect them not to be merged upon the (updated) default values in the chart first? Especially because that’s the usual behaviour in helm upgrade.
At least to me this is very unintuitive, because I would expect a package manager to use the chart values as a base, then merge upon it my previous release values, and finally any additional values I’ve supplied with the upgrade.
Your upgrade may fail when this happens, because the templates are likely to fail with your out-of-date values structure. For example, if a new config section has been added to the chart, but your release values actually lacks that entire section, you’ll surely bump into some nil pointer errors.
Why is the flag like this? Quoting one of the maintainers from GitHub: “The design goal is to prevent changes from a new chart release’s values from automatically being applied.” Meaning, it is intentional (not a bug) and the behaviour of these flags will not be changed.
It is still very confusing, because the behaviour between those seemingly similar commands is so unintuitive and can cause your upgrade to break.
As for alternatives, there is an active GitHub issue from May 2020 with discussion about workarounds and the possibility of a new feature. A new flag like
--reset-then-reuse-values could be a future addition to Helm to clear this up (there is an open PR too).
In the meantime, if you want the actually expected
--reuse-values behaviour when the chart values have possibly changed, you should dump your old values into a file first, and then use it as a base without
helm get values example-loki > prev-values.yaml helm upgrade example-loki -f prev-values.yaml --set grafana.enabled=true
This way your previous values are merged to the updated chart values, and finally any additional values from the CLI are merged on top of that.
Knowing how these flags work should surely help you reduce debugging time when running helm upgrade. I hope that this article has been helpful for you in illustrating the differences between them.
I’ve tried to massage the information into this table:
If you ever need to figure out a specific scenario, I recommend creating two local charts via
helm create test-chart-1 and
helm create test-chart-2 and upgrading between them, e.g.
helm install test test-chart-1 --set foo=bar && helm upgrade test test-chart-2 --reset-values && helm get values --all test.
I’ve also gathered all the infographics from this article into one big image, so you can pan and zoom around it if that helps you notice the differences:
What did you think of this article? Did we miss something?
Let us know at email@example.com!