13

I'm running a node.js EB container and trying to store JSON inside an Environment Variable. The JSON is stored correctly, but when retrieving it via process.env.MYVARIABLE it is returned with all the double quotes stripped.

E.g. MYVARIABLE looks like this:

{ "prop": "value" }

when I retrieve it via process.env.MYVARIABLE its value is actualy { prop: value} which isn't valid JSON. I've tried to escape the quotes with '\' ie { \"prop\": \"value\" } that just adds more weird behavior where the string comes back as {\ \"prop\\":\ \"value\\" }. I've also tried wrapping the whole thing in single quotes e.g. '{ "prop": "value" }', but it seems to strip those out too.

Anyone know how to store JSON in environment variables?

EDIT: some more info, it would appear that certain characters are being doubly escaped when you set an environment variable. E.g. if I wrap the object in single quotes. the value when I fetch it using the sdk, becomes:

\'{ "prop": "value"}\'

Also if I leave the quotes out, backslashes get escaped so if the object looks like {"url": "http://..."} the result when I query via the sdk is {"url": "http:\\/\\/..."}

Not only is it mangling the text, it's also rearranging the JSON properties, so properties are appearing in a different order than what I set them to.

UPDATE

So I would say this seems to be a bug in AWS based on the fact that it seems to be mangling the values that are submitted. This happens whether I use the node.js sdk or the web console. As a workaround I've taken to replacing double quotes with single quotes on the json object during deployment and then back again in the application.

jophab
  • 5,356
  • 14
  • 41
  • 60
Vadim
  • 17,897
  • 4
  • 38
  • 62
  • 1
    How do you write it to the variable? Is it a JSON string or Object? Have you tried calling JSON.parse on it? – Evan Shortiss Oct 24 '14 at 18:08
  • @eshortie It's a string and when I call JSON.parse on it, it barfs since there are no quotes. – Vadim Oct 24 '14 at 18:13
  • Strange. When I do the following on my machine they both work as expected: $node > process.env.MYVARIABLE = '{ "prop": "value" }' '{ "prop": "value" }' > process.env.MYVARIABLE '{ "prop": "value" }' > process.env.MYVARIABLE = { "prop": "value" } { prop: 'value' } Could it be the Amazon env? Apologies, it seems SO strips comment formatting. – Evan Shortiss Oct 24 '14 at 18:51
  • @eshortie yes, it definitely looks like AWS is doing some funky pre processing. I've updated the question with some more findings. – Vadim Oct 24 '14 at 19:27
  • @Vadim I'm having a similar issue with placing a JSON doc in an AWS/EBS METEOR_SETTINGS env variable. See: http://stackoverflow.com/questions/34761577/how-to-config-meteor-on-aws-ebs-using-meteor-settings-environment-variable Meteor's parsing of the env variable is internal and difficult to override, thus I have no practical way to employ the workaround you've mentioned in the UPDATE section. I am wondering thou, were you ever able to solve it 'the right way'? – tivoni Jan 13 '16 at 08:43
  • @tivoni no unfortunately I was not able to solve it. – Vadim Jan 13 '16 at 15:35
  • seems to still be an issue. I just tried most of what OP did before finding this – agmin Jul 18 '16 at 21:39
  • 1
    Still an issue as of today. My workaround is to use single quotes and replace them with double quotes. This works fine as long as you don't have single quotes in your variables. – adnan Oct 30 '16 at 20:21
  • Did you try with escape() or encodeURIComponent() ? – Jose Jun 26 '18 at 05:09

1 Answers1

3

Use base64 encoding

An important string is being auto-magically mangled. We don't know the internals of EB, but we can guess it is parsing JSON. So don't store JSON, store the base64-encoded JSON:

a = `{ "public": { "s3path": "https://d2v4p3rms9rvi3.cloudfront.net" } }`
x = btoa(a) // store this as B_MYVAR
// "eyAicHVibGljIjogeyAiczNwYXRoIjogImh0dHBzOi8vZDJ2NHAzcm1zOXJ2aTMuY2xvdWRmcm9udC5uZXQiIH0gfQ=="


settings = JSON.parse(atob(process.env.B_MYVAR))
settings.public.s3path
// "https://d2v4p3rms9rvi3.cloudfront.net"
// Or even:

process.env.MYVAR = atob(process.env.B_MYVAR)
// Sets MYVAR at runtime, hopefully soon enough for your purposes

Since this is JS, there are caveats about UTF8 and node/browser support, but I think atob and btoa are common. Docs.

Sam H.
  • 4,091
  • 3
  • 26
  • 34