Resource attribute JSON quotes getting stripped?

I’m trying to provide docker registry credentials to my DO droplet using this resource: Terraform Registry

I provide that value to templatefile to create a cloud-init.yaml file:

user_data  = templatefile("cloud-config.yaml.tftpl", {
  # ...
  docker_config =
  # ...

Then, in cloud-init, I save that file like so:

# ...

  - path: /tmp/
    permissions: "0700"
    content: |

      # ... 
      echo "${docker_config}" > /home/${username}/.secrets/docker/config.json
      # ...

  - "/tmp/ > /var/log/init.log 2>&1"

Trouble is, the final contents of config.json has all of the quotes (") removed, so the file is not valid JSON. :frowning:

Why this is happening?

1 Like

Ok, I didn’t realize wasn’t already JSON-encoded, but rather a Terraform value.

Passing that value through the jsonencode function gives me the JSON I was expecting.

1 Like

Thanks for updating your post with the resolution!

Thanks for sharing your solution indeed!

Note that you are passing a value though a shell script here, and so you may still run into problems because shell escaping syntax does not exactly match JSON string escaping syntax. For example, a JSON string is allowed to include the literal sequence a$b without escaping, but a shell will understand $b as interpolation of the variable b.

For Unix-style shells, a robust way to pass literal values is to use single quotes ' and then replace any literal quotes in your value with an escape sequence, like this:

"command '${replace(input, "'", "'\\''")}'"

I expect that in some fonts the sequences of double and single quotes here will be hard to follow, so: this is replacing any ' character with the sequence '\'', which is shell syntax for “end the current single quotes, insert a literal single quote, and then start a new single quotes sequence”.

Unix-style shells treat the contents of single quotes literally aside from the closing single quote character, so this should successfully pass through any string value without it being misinterpreted by your shell.

(Note for future readers: this strategy is not applicable in a Windows command script or in a PowerShell script because they use different escaping rules. The above is for Unix-style shells only.)

Thanks of the additional encoding notes! I think I actually ran into that issue for a separate Terraform resource (random.random_password) when trying to generate a PostgreSQL role password that contained special characters like <>$! etc.