Heroku didn’t invent ENV variables nor did it dream up the idea of using them for app config. This has been in use long before Heroku existed. I’ll give Heroku credit for making it common knowledge and spreading the use of these concepts, though.
yeah I never suggested that heroku invented environment variables, and the idea that environment variables weren't common knowledge before heroku came along is ... let's say at best revisionist.
If you remember the world before 12 factor you know that even if motivated by self serving incentives, Heroku making this mainstream has been an overall win for the entire industry and we are generally better and more secure for them having done so. We are still benefitting from all of this today, and Heroku who championed it is making death rattles.
While valid points in many contexts, I've seen many other contexts where following this principle/pattern a/ yields none of its benefits b/ results in very significant business impact.
Here is some obvious case observed many times.
A small and very fast pace team builds a server application having limited to no external dependencies. No db even.
Just a server doing stuff.
It does have some config yes, many many key/value pairs even, a config file ended up with a dozen properties just to control Req per sec limits and such.
Now just to deploy the thing, since of course env defined configurations is where things belong in best practice, the dev team setup a process to peer review those env values and despite all of that, fail to get the app running.
Human errors happen but since more mistakes and release delays were caused by misconfiguration than any other reasons, the keen and bright enginnering team all agreed it would be better to have a config repo. One genius in the group argued that having a config service would be even neater than have the app read from a git repo! The whole got so hyped and of course spend the whole next sprint building and testing that. Brilliant, it worked!
Except that of course outages happened, of course. Outages happen.
Bringing down all environments one by one, hence blocking pretty much everyone. Everything went down because hey, since we made that effort which took for longer than we thought to build a config service and have our app reads from it, one of the dev minds thought it was a genius idea to have the app reload the config every 5 mins at runtime so that if a configuration change was made, no need to even restart anything.
Of course error handling wasn't robust and well tested since the boss reminded the team we've got to ship a product by the end of the quarter and solving the universe can maybe wait 5 or 10 years after the IPO.
Team resorted to simply track the config in the repo. Kept the runtime reload of the config and things worked just fine.
Things can be done right and impacts could have been avoided. The example may seem like a twisted case since these were all configurations, not environment specific values.
But I've just seen so many occurences of env variables being separated from the application repo costing so much and distracting contributors for no benefit that I have grown very cautious of it.
The intent of this part of 12 Factor comes from the Bad Old Days when devs didn't run their own stuff in production. There was a dev team who could push code and cut releases, and an ops team who would then deploy the releases, and who was paged when things blew up.
If you store the database hostname/credentials, as an example, in the "code" (either literally in the app code, or in a config.ini that lives in the repo and gets baked into a release), then the ops people can't quickly repoint the app at a hot-spare database during an incident: they'll need to edit the repo, push it, cut a new release, etc. If there is a long build step (as for a C++ app, for example), then this isn't really tenable during an outage. If this is in an environment variable, their normal deployment scripts can make the change for them.
I agree that this is probably not necessary anymore if your team is all wearing both hats (dev and ops), and its just as quick to make an edit to the repo and cut/deploy a new release as it would have been for the Ops team to run their deployment script in the old days.
Great you pointing out the presence vs absence of dedicated operation enginners. Also that things have evolved more than a bit in team structures and tooling.
Even when ops are perfectly comfortable with git, they are rarely keen on touching dev repos even if deployment times were tenable.
If code changes need peer reviewed, how so configuration values don't get treated at least the same way?
Secrets in clear are obviously a no go, I feel though that encrypted secrets in repos has become reasonably simple with mature tooling in this area.
Ansible's fast growth got cut short once people started to hear k8s at every meet ups perhaps.
Secrets in the repo is actually something I've seen for a long time, and there's not much tooling necessary for it beyond just shelling out (yes, I know) to gpg in your deploy scripts. I saw this on CVS-based projects very early in my career, which then fizzled out as the "12 factor style" (secrets in ENV vars) took over.
Can I ask what the modern solution for this is?
Also:
> If code changes need peer reviewed, how so configuration values don't get treated at least the same way?
The easy answer to this is a CODEOWNERS file, with the app code being owned by the devs, and the config being owned by ops. But again, not sure how to do this for secrets without their being plaintext in the repo. Do any code review tools support encrypted content?