Live data from Hacker News

Don’t use environment variables for configuration

nibblestew.blogspot.com

231–240 of 296 posts

Re: Don’t use environment variables for configuration

#231
If my program needs more than a couple arguments, I prefer a YAML configuration file. I usually try to enable environment variable substitution in that file. This makes configuration more natural when/if the program is run in a container (you don't need to volume-mount a file); and it gives the user flexibility in how they configure the program.

To each their own, I suppose.

Re: Don’t use environment variables for configuration

#232

"Environment variables is exactly this: mutable global state." No it isn't. Every time you start a process, it gets a set of environment variables of its own, which won't be changed by any further changes in the parent process. This is the opposite of how global variables work and is exactly how function arguments work. The rest of the article isn't very good either. The examples of running a program with two differe…

> which won't be changed by any further changes in the parent process.

You can attach to a process and call setenv in gdb, so there is a loophole somewhere.

I'm not encouraging this, just pointing out that having a nice binary which reads config, cli, and environment once is still required. Regardless of how you pass that information into your binary.

Re: Don’t use environment variables for configuration

#233
post #15

Easy fix (if it's the shared, mutable state which bugs you): * Create one class responsible for ingesting env vars at startup. * Call it from main, and abort early with nice messages if it fails to read something. * Now you have a nice (preferably immutable) class which guarantees the config is in a 'good state', and is self-documenting because it lists all the keys it uses to lookup env vars with.

If The same pattern works well in python at the module level, if your application is setup as a package. A module config.py sets a bunch of python variables like

    import os
    
    ENV_VAR=os.environ.get('ENV_VAR', default_value)
then the rest of the application can grab configuration with

    from .config import ENV_VAR
Since the assignment code executes on import, all config is read in when any piece of it is first used, consistency checks and logging can be written into the config.py module as normal python statements, config values can be cast to appropriate types (raising exceptions if they fail), etc.

Re: Don’t use environment variables for configuration

#234
post #218

I don't understand how a blog post like this can garner, at time of writing, a hundred upvotes. Normally these types of strong statements "Don't do X/Don't use Y" are attention seeking titles with inversely proportional interestingness of its content. That's the first red flag. The second red flag is that the article is not proof-read: from just the first few minutes of skimming, I found two errors that make the text…

Such a shame, Enviroment variables are indeed difficult to work with sometimes, who sets them? in which file? Who can/will override them? typo's are also not being caught because editors dont have lists of possible variable and/or what value they are allowed to contain. you might also lose them on different containers.

Enviroment variables should be part of cgroups in some way. I dont like that any program can modify the PATH variable as example. seems like a recipe for disaster in privilege escalation.

Re: Don’t use environment variables for configuration

#235
post #218

I don't understand how a blog post like this can garner, at time of writing, a hundred upvotes. Normally these types of strong statements "Don't do X/Don't use Y" are attention seeking titles with inversely proportional interestingness of its content. That's the first red flag. The second red flag is that the article is not proof-read: from just the first few minutes of skimming, I found two errors that make the text…

Yes. At the same time, the post missed an appropriate case for avoiding environment variables: when you want dynamic configuration for your services, where configuration values can be changed at runtime without requiring a full redeploy of all the instances.

Of course, that brings its own set of complexity which should be carefully weighed against requirements.

Environment variables are still one of the simplest—and yes, most deterministic ways—to alter behavior of a program.

Re: Don’t use environment variables for configuration

#236
One perspective from this thread: environment variables end up denoting different levels of persistence in interactive, server, and containerized applications. For interactive apps, environment variable configs tend to sprout up for _persistent_ configurations e.g. HOMEBREW_NO_AUTO_UPDATE - we want the behavior to change, but we don't want to pass a flag to make that change every time.

For server-like applications, env vars denote a _transient_ change in behavior e.g. FLASK_DEBUG=1 python -m flask ... to turn on different behavior in that instance of the application. Persistent configuration changes go to a config file or similar.

For containerized applications, env vars are back to denoting _persistent_ changes in configuration since we bake the values in to deployed containers via whatever orchestrator.

TFA seems to be assailing the first perspective, which is actually reasonable. Sticking secrets and configuration into the shell environment for each tool is not great. Transient config via args and persistent config via files makes lots of sense.

Even in that setting though, there is probably a role for environment variables when spooky-action-at-a-distance changes are required in sub (sub- (sub- ...)) processes / libraries where passing configuration through each caller would be a pain.

Re: Don’t use environment variables for configuration

#237
post #218

I don't understand how a blog post like this can garner, at time of writing, a hundred upvotes. Normally these types of strong statements "Don't do X/Don't use Y" are attention seeking titles with inversely proportional interestingness of its content. That's the first red flag. The second red flag is that the article is not proof-read: from just the first few minutes of skimming, I found two errors that make the text…

Such a shame, Enviroment variables are indeed difficult to work with sometimes, who sets them? in which file? Who can/will override them? typo's are also not being caught because editors dont have lists of possible variable and/or what value they are allowed to contain. you might also lose them on different containers. Enviroment variables should be part of cgroups in some way. I dont like that any program can modify…

> who sets them? in which file? Who can/will override them?

The ops team. Environment variables are a great way of separating operational concerns from business logic. Environment variables are great because your application is agnostic about how the configuration is sourced. Let the ops/infra team handle that.

> I dont like that any program can modify the PATH variable as example.

And ... why not? Child processes can't modify the environment of parent processes. Environment variables flow downwards.

Re: Don’t use environment variables for configuration

#238
post #186

Earlier quoted context omitted.

So then the real secret is the key, which is provided "externally" ... how? Through command line parameters, some other config file, or environment variables? :P

Another encrypted config file. Obviously.

Encrypted files all the way down.

Re: Don’t use environment variables for configuration

#239

Earlier quoted context omitted.

@ajarmst is that last related idea you quoted your own? That’s a powerful expression of how I see human culture: question everything, but remember to respect the ideas of the people who came before you. There might be a baby in the bath water you’re discarding.

It's a restatement of the lesson of Chesterton's Fence. There is a fence somewhere you wish to get rid of. Nobody around knows why it was there in the first place. No one will let you tear it down until somebody figures out why it was put there in the first place. The important take away, is that before changing something, one should understand the history of a thing, or one runs the risk of being a victim of the sam…

[deleted]

Re: Don’t use environment variables for configuration

#240
> Environment variables is exactly this: mutable global state.

Not really; environment variables can't be externally changed once they're passed in. If it were true mutable global state, some external process could change their value while a program is running. Or the program could change the value of the environment variable in the shell that launched it. Either of those would be horrifying.

In other words, environment variables could be worse. They could also be better. My main objection to environment variables is that they're not a discoverable interface. Ideally, it should be possible to find out what environment variables a program accepts without running the program (or grepping the source code for "getenv"), and in most cases it should be possible to enumerate the valid values.

Environment variables are just one of many things about they typical POSIX / ANSI C interface that have been around so long people don't even question it anymore.

Post reply on HN