Reading a list of strings and a number as config values from environment variable

I’m deploying my Phoenix app with edeliver and distillery and reading config values from environment variables. I can read normal strings just fine, but how do I handle 1.) a list of strings and 2.) numbers?

For 1, the list of strings:
In my config/prod.exs i have allowed_users: ["${ALLOWED_USERS}"],

Here is my sys.config file with the problematic variable:
allowed_users,[<<"${ALLOWED_USERS}">>]},

My environment variable being exported is (i’ve escaped the strings, but it’s not really helping):
export ALLOWED_USERS="\"john\", \"alice\""

When I don’t use an environment variable in my config file and just enter the values directly, then the compiled sys.config looks as follows, so that’s what I need:
allowed_users,[<<"john">>,<<"alice">>],

I can export the following export ALLOWED_USERS="john\">>,<<"alice" as the environment variable and that works, but it feels clunky.

Also, question 2. How can I get a number for a config value that is exported as an environment variable?
My config/prod.exs has this variable enable_salt_workers: "${ENABLE_SALT_WORKERS}", which
i export as export ENABLE_SALT_WORKERS=true, but it ends up as a string in sys.config as follows {enable_salt_workers,<<"true">>}, instead of {enable_salt_workers,true},

Any help would be appreciated.

Environment variables are always simple strings, nothing more. If you want to encode something more complex into them, then you’ll have to parse them after reading them.

If you have a lot of more complex “stuff” that you need to communicate via environment variables, then you might want to consider a string of JSON as the value…

2 Likes

Thanks for the feedback @sribe. After some more digging, I noticed this is a common issue in Elixir.

This isn’t an Elixir thing, this just just how Environment Variables work regardless of any operating system I’ve seen, they are just a single string, not lists or numbers or anything of the form, hence why parsing is required regardless of the language.

3 Likes

Two things to keep in mind:

  1. mix.exs is not some simple template, it’s full-blown Elixir, so you can use the full language for parsing, including defp of some some helper functions, so enable_salt_workers: my_parse_env_list("${ENABLE_SALT_WORKERS}")

  2. All .exs files are run at compile time; so when you pull in env vars in prod.exs, you’re getting the ones on your dev system, not the ones from your production system. To actually use env vars loaded at launch instead of build, you have to read them in elsewhere, when your application is starting up–sounds like you may have already found some of the posts on how to do that.

2 Likes

Thank you for the help. I haven’t decided yet which route to take to best solve this.

Thanks @OvermindDL1, good to know.

1 Like

Sounds like you have outgrown environment variables and you might need to use etcd. Environment variables are awful to store data in. I would not recommend the character escaping hell they will put you through even for basic JSON or a few key-value pairs.

1 Like

Thank you @dimitarvp! That looks useful. I’ll look into it.