helm: Default value doesn't work when overriding array parameters partially via --set

Hi,

I met a strange thing that we have some parameters of a subchart of array type and they are in an custom values.yaml:

mysubchart: portList: - port: 87 endPort: 87 protocol: udp nodePort: 31459

When I override them via --set like this command they are working fine: helm install mychart --name mychart -f port_values.yaml --set myvalue.port[0].port=83 --set myvalue.port[0].endPort=83

But when I move these parameters to default values.yaml and run with same helm install command without -f, they are not working properly. The result will be:

portList: - port: 83 endPort: 83

That means only the overriden values were rendered, the other two values “nodePort” and “protocol” are missing although they have default value. I tried with latest helm version 2.13.0 and it’s the same.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 13
  • Comments: 27 (6 by maintainers)

Commits related to this issue

Most upvoted comments

This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.

Is there any updates on this bug ?

I’ve just encountered this bug, but it’s very annoying since there are arrays everywhere: containers, deployments, ports, etc.

So if I can’t partially override an array with --set option and without nulling all other values of that array, I think it makes arrays practically unusable in Helm 😢

Hi all,

I experiencing the same issue with the array overrides through --set. I read carefully all the comments and I understood that, at the moment, helm is not able to merge what we pass through --set option with the original values.yaml. What it is still not clear to me is why helm become able to do it when I specify which values.yaml file need to be used through the -f/–values option. Could someone help me understanding this?

Thanks

Did nobody merge this fix? Helm still dropping previous data from the overwritten array:

> helm template array-overwrite/
---
# Source: array-overwrite/templates/range.yaml
## i::0, db::map[external_name:db1.env.external.name name:db1 user_pass:5rPgmqjQtaGeBpkwyHEfurmgwSyBwjFC]
## i::1, db::map[external_name:db2.env.external.name name:db2 user_pass:VpRnlpHS0lqZqTZ1DcF0TSxduCGQSUIw]

> helm template array-overwrite/ --set dblist[0].name=db0
---
# Source: array-overwrite/templates/range.yaml
## i::0, db::map[name:db0 user_pass:RNMfuOYTwFIEvOpayhFJ7YtHRMTncjVe]

> helm template array-overwrite-values-only/
---
# Source: array-overwrite-values-only/templates/range.yaml
## i::0, db::map[name:db1 user_pass:9rSOuCtsW5H70EVF69Azk7Xb2GmjyJBZ]
## i::1, db::map[name:db2 user_pass:eRB66jnH0UWNiAk12LEUdkro7ZhWRqbl]

> helm template array-overwrite-values-only/ --set dblist[0].name=db0
---
# Source: array-overwrite-values-only/templates/range.yaml
## i::0, db::map[name:db0 user_pass:0TTux8UcFUBPzeEr4zV84s2nDT6Ue9CD]

> helm version
version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}

Attached minimal charts. array-overwrite-values-only.zip array-overwrite.zip

@heatherlv This looks like a bug to me.

I investigated this with output shown below. As you found, values are overwritten (nameand nodePort). The values doc covers this.

$ cat chrt-5711/values.yaml 
ports:
- port: 80
  targetPort: 80
  name: http2
  nodePort: 31459

$ cat chrt-5711/templates/configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  ports: |-
    {{- if .Values.ports }}
    {{- range $index, $element := .Values.ports }}
    -{{- range $key, $val := $element }}
      {{ $key }}:{{ $val }}
    {{- end }}
    {{- end }}
    {{- end }}

$ helm install --set ports[0].port=83,ports[0].targetPort=83 chrt-5711/ --debug --dry-run
[debug] Created tunnel using local port: '38745'

[debug] SERVER: "127.0.0.1:38745"

[debug] Original chart version: ""
[debug] CHART PATH: /home/usr1/test/helm-charts/chrt-5711

NAME:   handy-donkey
REVISION: 1
RELEASED: Mon May 13 12:16:12 2019
CHART: chrt-5711-0.1.0
USER-SUPPLIED VALUES:
ports:
- port: 83
  targetPort: 83

COMPUTED VALUES:
ports:
- port: 83
  targetPort: 83

HOOKS:
MANIFEST:

---
# Source: chrt-5711/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: handy-donkey-configmap
data:
  myvalue: "Hello World"
  ports: |-
    -
      port:83
      targetPort:83

it would be nice to have this fixed, the limitation makes sense but it is weird and unintuitive for new users. The best workaround I have found is to replace arrays with maps wherever possible, for example, replace:

animals:
  - name: cat
    sound: meow
  - name: dog
    sound: bark

with

animals:
  cat:
    sound: meow
  dog:
    sound: bark

and in templates, replace

{{ range .Values.animals }}

with

{{ range $name, $animal := .Values.animals }}

Of course, not every list of objects has an obvious identifying field with a unique value that can be promoted to a key like .name is in this example; sometimes you end up coming up with pretty contrived keys (like descriptive names that aren’t even used in the template rendering) for maps like this. But if we’re committing to keeping array merge behavior so severely hampered, we should document this technique (or some other similar technique I haven’t considered) as a best practice.

The same problem here.

test:
  deployment:
  - containers:
    - containerPort: 
        value: 80
      nodePort: 31397

When making helm template --set test.deployment[0].ooo=ddd v1.2.8/

it’s overriding everything, and nulling other values

render error in "badchart/templates/frontend1-NodePort-service.yaml": template: badchart/templates/frontend1-NodePort-service.yaml:13:14: executing "badchart/templates/frontend1-NodePort-service.yaml" at <index (index .Values...>: error calling index: index of untyped nil

Refering to it:

- port: {{ (index (index .Values.test.deployment 0).containers 0).containerPort.value }}