Search code examples
kubernetes-helm

How can I pass imagePullSecrets, as it is defined in the default template, to helm via set commands


When you run helm create mychart it has imagePullSecrets defined like this:

spec:
  {{- with .Values.imagePullSecrets }}
  imagePullSecrets:
    {{- toYaml . | nindent 8 }}
  {{- end }

In default values file it looks like it's passing it a blank array:

imagePullSecrets: []

I already have a bunch of charts built from this default template that have this setting. Previously I didn't need to use imagePullSecrets so I just left it as is, but now I have some cases where I want to set this at deploy time via the cli.

Helm supports arrays now but this doesn't seem to work:

--set "mychart.imagePullSecrets[0].name={reg-creds}"

Returns:

Error: UPGRADE FAILED: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.imagePullSecrets[0].name): invalid type for io.k8s.api.core.v1.LocalObjectReference.name: got "array", expected "string"

Then I tried passing a string:

--set "mychart.imagePullSecrets='- name: reg-creds'"

Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.imagePullSecrets): invalid type for io.k8s.api.core.v1.PodSpec.imagePullSecrets: got "string", expected "array"

These error messages are infuriating. Is it possible to set this value with --set so I can avoid refactoring all my charts?


Solution

  • The helm install --set syntax is unique and complex. One unusual bit of syntax there is that a value {foo,bar} in curly braces sets the value to an array. In your example, then, --set object.path={value} sets the value to a single-element array; the error you see is that it needs to be a string instead.

    That means a simple workaround here is to remove the curly braces on the right-hand side of --set. There is also a --set-string option that forces the value to be interpreted as a string, even if it contains curly braces or commas.

    helm install ... --set "mychart.imagePullSecrets[0].name=reg-creds"
    #                       no curly braces around the value ^^^^^^^^^
    

    It might be clearer, and have a more standard syntax, to use a YAML file to provide this value instead.

    # image-pull-secrets.yaml
    imagePullSecrets:
      - name: reg-creds
    

    You can include this in a per-environment values file, or pass it as a standalone values file. In either case you'd use the helm install -f option to supply the file. It's fine to have multiple helm install -f values files.

    helm install ... -f image-pull-secrets.yaml