Earlier quoted context omitted.
On the facade environment variables may seem like they're orthogonal to global variables but they're not. Environment variables are scoped to the current process. This could be your shell, but it could also be a web server. This doesn't make them leak proof, but unlike global variables, environment variables have a scope. Environment variables are also used more widely as an API. Many CLIs have a command that when se…
> Environment variables are scoped to the current process. Obviously this is true in a sense. But for practical purposes, it depends on how the environment variables are set. For example, if I set them in my ~/.bash_profile, they're scoped to all bash processes that my current user runs. If I put them in /etc/profile, they're effectively global.
Don’t use environment variables for configuration
271–280 of 296 posts
Re: Don’t use environment variables for configuration
#272Earlier quoted context omitted.
I have no skin in this game, so to speak, so just curios. What kind of ways did you get burned by other things than env vars in a way in which env vars would not?
Mostly configuration stored in the database (who configures the database) or 3rd party configuration services without an SLA and config files that are either present or not. Env vars are really simple since they are completely decoupled from the app and you can have default values for all of them. You just need a single class that loads all config on startup and you can go from there (or fail if you don't have the ma…
The author's title is unfortunate: "Never use environment variables for configuration"
Not everyone is writing CLI scripts. Some are writing multi-environment software for the web. Some people care about git and distributed teams.
Let's say you backup and migrate a db which has config in the db. Well your other environment is using the wrong config! Now you're possibly using prod SMTP credentials and sending notifications to the wrong people because all you wanted to do was have live content and do some testing or show debug messages because you're on a test environment.
Web frameworks which have the HTTP host in the database drive me nuts. Why do you need that? Your webserver is responding on a domain name. Why do some store the absolute url in the db. It makes no sense. For the 3 people that want to serve up domainA.com but have all links readily be domainB.com maybe that makes sense.
Don't get burned people. For most things, just ignore this article, keep your secrets out of version control and keep your code ready to deploy to multiple environments. Decouple that. Your app should be able to work with various configurable services (SMTP, push notifications, database, etc) and you don't want that config in version control.
So either a file that's outside of version control with variables you set per environment or actual server environment variables.
Environment variables in many web languages are just namespaced globals. Still better than global variables. They serve a purpose.
The author has this:
int first_argument;
int second_argument;
void add_numbers(void) { return first_argument + second_argument; }
While it helps the author's agenda, that's not a legitimate example.
A real example would be a service provider which a developer would understand to have the sole purpose of pulling from environment or config values to initialize.
You wanted a Twilio client? Well, we know it needs some keys. Use environment variables. Boom. Everywhere you ask for this Twilio client you get the same instance with the config that that environment needs.
This is not a problem. It works well. Better than any alternative.
Author also says this "Environment variables is exactly this: mutable global state."
For some CLI applications maybe. But for web languages this is not accurate. Some languages, yes, you can mutate the env variables at runtime. But your code shouldn't rely on any mutable env vars. You can load those env vars into a config. Even cache it. Not allow mutations. Many modern frameworks support this or you could implement it yourself.
And if you have a CLI that really needs to be explicit about the environment vars to run? And not be different the next time you call it with no env vars? Well maybe take those as arguments?
Plenty of CLI apps that store config in json and have a wizard to set those credentials. AWS CLI as an example.
Now you got JSON as the author wanted. That can work across platforms. But guess what? You work on multiple clients and hosts and next time you call it? Well you might not be expecting that it had config for another client or app.
Same problem. The state was mutated. You called it again. You potentially got burned. Now you have to do the CLI wizard to reconfigure. Or you pass in explicit params if allowed.
Definitely a consideration if you are writing such a program. Do you make it explicit with arguments and options? Load from ENV vars? Have some CLI wizard and save to JSON?
The author's suggestion of JSON is no reason to toss out ENV vars. Just solves slight differences between Windows and Unix. Which is why you can program a CLI wizard if you care about that problem.
We don't need to say no to env vars because we want CLI app users across different platforms to have the exact same API. Setting up a JSON file is really lame to use a program. Which is why you see cli wizards when you run them.
Or things like "aws configure". And you still have CLI arguments and options availabe.
Re: Don’t use environment variables for configuration
#273I disagree with this post so strongly - having spent most of my career installing, configuring, and managing other people’s software. > The answer is that you, the end user, can not now. Every program is free to do its own thing and most do. If you have ever spent ages wondering why the exact same commands work when run from one terminal but not the other, this is probably why. If the same program is behaving differe…
I was thinking about this while reading the post. What's the best syntax language or syntax for configuration, if environment variables are too simplistic and full-fledged programming languages are too powerful? That's why I'm interested in Dhall, which is a configuration language that's limited to compile-time only–i.e. it can't do anything at runtime.
Re: Don’t use environment variables for configuration
#274Meanwhile I'll just say the following:
* Any config input, whether passed through env variables or config files or command line arguments or external services or telepathy, is handled by clients. Sure, anyone is free to directly call getenv() from whatever corner of the project, but to handle any input properly you need to use dedicated clients to handle common usecases such as input validation, logging, provide sane defaults, and layer config settings.
Re: Don’t use environment variables for configuration
#275Wrong. They are immutable global state. There is no way of updating a process environment set after it's started. Apart from corner cases (execve), env vars are immutable, therefore act like constants. And constants aren't bad, are they?
Re: Don’t use environment variables for configuration
#276Earlier quoted context omitted.
I have no skin in this game, so to speak, so just curios. What kind of ways did you get burned by other things than env vars in a way in which env vars would not?
Mostly configuration stored in the database (who configures the database) or 3rd party configuration services without an SLA and config files that are either present or not. Env vars are really simple since they are completely decoupled from the app and you can have default values for all of them. You just need a single class that loads all config on startup and you can go from there (or fail if you don't have the ma…
Re: Don’t use environment variables for configuration
#277Earlier quoted context omitted.
Mostly configuration stored in the database (who configures the database) or 3rd party configuration services without an SLA and config files that are either present or not. Env vars are really simple since they are completely decoupled from the app and you can have default values for all of them. You just need a single class that loads all config on startup and you can go from there (or fail if you don't have the ma…
>who configures the database or, what configures the database connection
Re: Don’t use environment variables for configuration
#278Earlier quoted context omitted.
Why I don't like environment variables: 1. I worry about programs dumping all their environment variables to log files - credentials are now on disk, ingested into log storage... 2. Environment variables are inherited by child processes by default. This is undoubtable useful. But it can also cause problems. I wish the ghosts of unix past had forseen the need for a way to mark particular variables as, say, 'sensitive'…
> I wish the ghosts of unix past had forseen the need for a way to mark particular variables as, say, 'sensitive' and 'noexport', allowing them to opt out of the default behaviour. The default behavior is a non-exported variable. If you want child processes to see it, you must export it.
See execve(2):
"envp is an array of pointers to strings, conventionally of the form key=value, which are passed as the environment of the new program. The envp array must be terminated by a NULL pointer."
You can confirm this my examining the the environment block that was passed in to your current shell with:
What you're referring to are actually "shell parameters", some of which may be marked for export. When the shell starts up, it parses the environment block and sets parameters based on what it finds, marking them all for export. And the shell uses only the parameters marked for export when constructing the environment block for a child process (which is passed to execve(2)/execveat(2) in the envp argument).Re: Don’t use environment variables for configuration
#279This attitude is how we ended up with Active Directory. One assumes that the author doesn't spend much time in a command-line environment. The option to set defaults for one's normal working environment is obviously of value, and environment variables are hardly exclusive of configuration files (~/.bashrc, makefiles, ...). The theory that complex syntax and statelessness are inherently good and cost-free is naïve to…
On the facade environment variables may seem like they're orthogonal to global variables but they're not. Environment variables are scoped to the current process. This could be your shell, but it could also be a web server. This doesn't make them leak proof, but unlike global variables, environment variables have a scope. Environment variables are also used more widely as an API. Many CLIs have a command that when se…
A gripe I have with environment variables is when they are used to modify a programs behavior deep inside it's belly and aren't treated like configuration input similar to program arguments.
Otherwise they are a universal way of configuring applications. Universal is good, universal is nice.
Re: Don’t use environment variables for configuration
#280Earlier quoted context omitted.
Mostly configuration stored in the database (who configures the database) or 3rd party configuration services without an SLA and config files that are either present or not. Env vars are really simple since they are completely decoupled from the app and you can have default values for all of them. You just need a single class that loads all config on startup and you can go from there (or fail if you don't have the ma…
They also work well with serverless environments, containers, etc., which can’t be said for some alternatives.
In practical terms, specifying environment variables in cleanly isolated and composable layers (defaults by user, a specific terminal session, a script that call another script or the useful program) is a major advantage over more enterprisey and monolithic mechanisms.