Search code examples
bashescapingkubernetes-helm

Passing a string containing curly brackets to helm caused: Error: failed parsing --set data: key


${CLIENT_ID} and ${CLIENT_SECRET} are both sourced from a yaml based properties file e.g

CLIENT_ID: 11111111-1111-1111-1111-111111111111
CLIENT_SECRET: '{aes}AM+JYP8t9ga1m6s111x1fjdfePL10v90RmbgWFdOjVdD/wlnszAbJad8aOI4qqMv6eSGaW2nfTF4PG2OYH+rx9K052TXNP6PGAAcRph9pl11'

using:

PROPERTIES_FILE="properties.yaml"
CLIENT_ID=$(yq r "${PROPERTIES_FILE}" CLIENT_ID)
CLIENT_SECRET=$(yq r "${PROPERTIES_FILE}" CLIENT_SECRET)

and then passed into my helm command for deploying my app:


echo ${CLIENT_ID}
# 11111111-1111-1111-1111-111111111111
echo ${CLIENT_SECRET}
# {aes}AM+JYP8t9ga1m6s111x1fjdfePL10v90RmbgWFdOjVdD/wlnszAbJad8aOI4qqMv6eSGaW2nfTF4PG2OYH+rx9K052TXNP6PGAAcRph9pl11

helm upgrade -i --debug  --namespace mynamespace release \
-f "charts/app/values.yaml" \
--set "app.configmap.dependancy.client_id=${CLIENT_ID}" \
--set "app.configmap.dependancy.client_secret=${CLIENT_SECRET}" \
"charts/app/"

charts/app/values.yaml contains:

app:
  ..
  configmap:
    dependancy:
      client_id: ""
      client_secret: ""

The problem is, I get this error when running the helm command:

Error: failed parsing --set-string data: key "AM+JYP8t9ga1m6s111x1fjdfePL10v90RmbgWFdOjVdD/wlnszAbJad8aOI4qqMv6eSGaW2nfTF4PG2OYH+rx9K052TXNP6PGAAcRph9pl11" has no value
No resources found.

Any idea why the prefixed {aes} is causing problems when passed into helm like this? The command works if I remove the {aes} prefix.


Solution

  • Helm tries to make it possible to pass some structured data in using --set and that's tripping you up here. In particular,

    Lists can be expressed by enclosing values in { and }. For example, --set name={a, b, c} translates to [a list of a, b, and c].

    So if you --set 'key={aes}AM+JYP8...', the {aes} part looks like that list syntax but then there's things after it that Helm doesn't understand.

    You can backslash-escape the curly braces, though that's a little tricky to do in shell syntax. There's a --set-string option (documented in the Helm 2 documentation but still present in Helm 3) that might be able to do this. Possibly the most straightforward path, though, is to write out your own custom YAML values file:

    #!/bin/sh
    PROPERTIES_FILE="properties.yaml"
    CLIENT_ID=$(yq r "${PROPERTIES_FILE}" CLIENT_ID)
    CLIENT_SECRET=$(yq r "${PROPERTIES_FILE}" CLIENT_SECRET)
    
    cat >values.tmp.yaml <<EOF
    app:
      configmap:
        dependancy:
          client_id: "${CLIENT_ID}"
          client_secret: "${CLIENT_SECRET}"
    EOF
    
    helm upgrade -i --debug --namespace mynamespace release \
      -f values.tmp.yaml charts/app
    

    (You can have multiple helm install -f options if you need to. The chart's values.yaml is read in automatically, and is overridden by command-line options.)