Problem passing in a variable from a shell script into a deployment yaml

Viewed 30

In a shell scrip I want to assigning a variable what to use in a value in a deployment. For the life of me I can not figure out how to get it to work.

My helm deploy script file has the following in order to set the value to use my variable :

   --set AuthConfValue=$AUTH_CONF_VALUE

And I have this in the deployment.yaml file in order to use the variable :

   - name: KONG_SETTING

   value: "{ {{ .Values.AuthConfValue }} }"

If I assign the variable in my shell script like the following :

   AUTH_CONF_VALUE="ernie"

It will work and the value in the deployment will show up like so:

   value: '{ ernie }'

Now if I try to assign the variable like this:

   AUTH_CONF_VALUE="\\\"ernie\\\":\\\"123\\\""

I will then get the error error converting YAML to JSON: yaml: line 118: did not find expected key when the helm deploy runs.

I was hoping that this would give me the following value in the deployment :

   value: "{ "ernie":"123" }"

If I hardcode the value into the deployment.yaml with this:

   - name: KONG_SETTING

   value: "{ \"ernie\": \"123\" }"

and then run the helm deploy it will work and populate the value in the deployment with this -

   value: "{ "ernie":"123" }"

Can someone show me if/how I might be able to do this?

1 Answers

The Helm --set option also uses backslash escaping. So in your example, the $AUTH_CONF_VALUE variable in the host shell contains a single backslash before each quote, which is consumed by --set, so .Values.AuthConfValue contains no backslashes at all, and you get invalid YAML.

If you want to keep this as close to the existing form as you can, let's construct a string with no backslashes at all (and hopefully no commas or brackets either, since those also have special meaning to --set)

AUTH_CONF_VALUE='"ernie":"123"'
helm install --set AuthConfValue="$AUTH_CONF_VALUE" .

When Helm expands a template it doesn't know anything about the context where it might be used. In your case, you know

  1. .Values.AuthConfValue is the body of a JSON object
  2. If you surround it in curly braces { ... } then it should be a valid JSON object
  3. You need to turn that into a correctly-escaped YAML string

Helm contains a lightly-documented toJson function that takes an arbitrary object and converts it to JSON; any valid JSON is also valid YAML. So the closest-to-what-you-have approach might look like

- name: KONG_SETTING
  value: {{ printf "{%s}" .Values.AuthConfValue | toJson }}

If you're willing to modify your deploy process a little more, you can have less escaping and more certainty. In the sequence above, we have a string that happens to be a JSON object; what if we had an actual object? Imagine settings like

# kong-auth.yaml
authConf:
  ernie: "123"

You could provide this file at install time with a helm install -f option. Since valid JSON is valid YAML, again, you could also provide a JSON file here without changing anything.

helm install -f kong-auth.yaml .

Now with this setup .Values.authConf is an object; the only escaping you need to do is standard YAML/JSON escaping (for example quoting "123" so it's a string and not a number). Now we can use toJson twice, once to get the {"ernie":"123"} JSON object string, and a second time to escape that string as a value "{\"ernie\":\"123\"}".

- name: KONG_SETTING
  value: {{ .Values.authConf | toJson | toJson }}

Setting this up would require modifying your deployment script, but it would be much safer against quoting and escaping concerns.

Related