Live data from Hacker News

Don’t use environment variables for configuration

nibblestew.blogspot.com

221–230 of 296 posts

Re: Don’t use environment variables for configuration

#221
post #167

Earlier quoted context omitted.

What better place is there to store credentials?

A config store like Vault. Of course, that needs credentials too, which are typically a file on the file system. IMO, people are overly sensitive about environment vars. They are really no worse than files on the file system - both can be accessed if you're a privileged user on that machine.

Vault should be source of those env variables. Via some predefined initcontainer or something like that, to which devs don't have access to.

Re: Don’t use environment variables for configuration

#222
Calling env vars 'global mutable variables' is pretty misleading. The example C code is a terrible strawman, and makes it appear that the author is simply unaware of some core compsci/programming concepts.

Environment variables behave much more like dynamic variables (AKA dynamically scoped/bound variables), rather than global variables https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynam...

In particular, we can override env vars for a particular call, without affecting anything else. For example, consider the following script:

    echo "BEFORE $FOO"
    FOO=bar printFoo
    printFoo
    echo "AFTER $FOO"
If we run this script with 'FOO=foo', and assuming that the program 'printFoo' simply prints the 'FOO' env var, we will get:

    BEFORE foo
    bar
    foo
    AFTER foo
The variable 'FOO' wasn't mutated (since the value remains the same across lines 0, 2 and 3); it's also not globally scoped (since line 1 saw a different value). Rather, each process is run with its own environment, whose initial contents is inherited from the scope that invokes the process; plus extras/overrides, like 'FOO=bar' above.

Env vars are mutable, and mutating an env var acts differently to mutating a dynamic variable: dynamic scope looks up variables on the call stack, so mutations high up the stack will be visible after returning. Instead, env vars are copied from parent to child at each new scope (process), so mutations are only visible to that process and any subsequent subprocesses. In fact, that makes env vars even less 'globalish' and 'mutableish' than ordinary dynamic variables!

For example: if 'printFoo' finished by mutating 'FOO' to equal 'baz', it wouldn't affect the above script at all. Even line 2, which "inherits" the script's FOO, would only be mutating its own copy of 'FOO', which doesn't affect the script's variable.

In any case I highly recommend to avoid mutating env vars, for the same reason I avoid mutating any variables, regardless of language; unless there's a specific reason to. If we treat env vars in an immutable way, then they act exactly like dynamic variables.

As an example of dynamic variables, consider the following Lisp code:

    (write-line (concatenate "BEFORE " FOO))
    (let ((FOO "bar"))
      (printFoo))
    (printFoo)
    (write-line (concatenate "AFTER " FOO)
The '(let ((FOO "bar")) ...)' construct acts like the 'FOO=bar ...' of the script.

Not only do I find env vars very useful for config, I also find dynamic scope is very under-utilised in "proper" (non-shell) languages. For example, dynamic scope is a great way to do dependency injection: rather than passing around extra arguments, or adding a bunch of private fields to objects, etc. we can just reference the dependency with a dynamic variable, and open a new scope whenever we want to set its value (at an application's entry point, or in a test, etc.)

Re: Don’t use environment variables for configuration

#224
post #93
post #73

Earlier quoted context omitted.

What's the alternative? That's how make, cmake, msbuild, ninja,docker, and basically every other build tool I'm aware of works

Make doesn't work like that.

Wait, make has a global state? I was under the impression most make targets are stored somewhere in the project itself (like a build/ directory). I think this is a fine approach, BTW. I think global state should be avoided unless necessary.

Re: Don’t use environment variables for configuration

#225
post #187

This 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…

[deleted]

Re: Don’t use environment variables for configuration

#226
post #59

Earlier 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…

>who configures the database

or, what configures the database connection

Re: Don’t use environment variables for configuration

#227

Earlier quoted context omitted.

I don't get this. From the same perspective you can argue global variables have scope too since they are "scoped to the current process". It's not like other processes can access your global variable, that's a very low bar for a scope.

The difference here is that a running shell (including the shell environments that services run with in) are an abstraction layer about managing processes. Within that abstraction layer, each process can have its own unique environment variables that they can change and manipulate independently. That makes them not global. Within a process the top level abstraction is the process itself, and anything underneath (clas…

Makes sense, thanks.

Re: Don’t use environment variables for configuration

#229

This 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…

@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.

The sentiment certainly isn’t original. The phrasing sounds like me, though. I can get pretty pedantic.

Re: Don’t use environment variables for configuration

#230
I think if machines are treated like single purpose cattle then environmental variables are fine.

But for a single system with lots of different applications and functionality going on, you kind of run into the same problem as you have with mutable global variables.

Post reply on HN