I totally agree with Nick Craver “I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…”.
A little event in the early 1990s made me cautious whenever I see environment variables in use.
One of my clients had a network that had to be separated into three logical areas: one for workstations communicating with a certain server and some equipment, and another for a different server and other equipment, and finally a bunch of semi-local workstations that did some peer-to-peer and specialised equipment communication.
For that era, this was a LOT of stuff to manage.
Since users always were working from the same computers, and there was very little overlap between the areas, I created a bunch of login scripts. Since this was Novell NetWare 3.x era, you only had default, system and user login scripts (see [WayBack] NetWare 3 Login Script Fundamentals), of which only system+default or system+user could be combined. No groups scripts yet (:
So I introduced an environment variable NETWORK
that would hold the kind of logical network.
Boy was I surprised that a few days later, the head of administration came to me with a problem: one of his administration programs – despite no documentation mentioning anything about such a feature – suddenly asked for a license!
A few hours of phone calls and trying later, we found the culprit: that software had an undocumented feature: when the NETWORK
environment variable was set, it assumed a large corporate, with a very special license feature.
That was the day, I started to be wary of environment variables.
The workaround was simple: have the program being started with a batch file, temporarily clean the NETWORK
environment variable, then run the application, and finally restore the environment variable.
Inspired by two tweets I got within a few days time:
- [WayBack] James Newton-King ♔ on Twitter: “This is it. The end of my career. I’ve fought this bug for 3 hours and I can’t defeat it. The bug defies logic and reason. The rest of my days will be spent in eternal struggle against an amorphous foe, destined to- Oh, there was a typo in an environment variable. Never mind.”
- [WayBack] Nick Craver on Twitter: “Maybe I’m a minority opinion the way things are going, but I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…ugh. I do not care for them.”
- [WayBack] Thread by @Nick_Craver: “Maybe I’m a minority opinion the way things are going, but I absolutely hate environmental variables for configuration. They’re brittle, the […]”
Maybe I’m a minority opinion the way things are going, but I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…ugh. I do not care for them.The most common answer I get on “why?” is “that’s the cross-platform way, everyone supports it”.Okay, yeah sure…I agree that we’re at the least common denominator. My issue is settling for that. I don’t think most things should. We can do far better. Options already exist.
I love the way .NET Core does this – IOptions is very pluggable and one of my favorite API designs because it fits so many scenarios, including complex deployment and multi-tenant things we have here.It’s defaulting straight to “make it an environmental variable” that gets me.
I’ve seen so bugs where a thing works forever but stops because some sysadmin somewhere deployed a GPO that sets an environmental variable deployed to many machines that silently changed behavior of apps that haven’t been deployed in years, just happens on restart and…ugh.That’s just one example, there are many.“It works on my machine” is a problem. Environmental variables magnify that problem immensely. They’re a maybe permanent, maybe ephemeral, maybe local, maybe global external state that adds more to control, break, reason about, and debug.
“Why does this app work, but this one doesn’t?”“After 2 days of debugging we found out this one runs as account X with variables Y and it has the SDK path correctly set, the other one didn’t have that variable”
“…I quit.”
- [WayBack] Thread by @Nick_Craver: “Maybe I’m a minority opinion the way things are going, but I absolutely hate environmental variables for configuration. They’re brittle, the […]”
–jeroen