Hacker News new | past | comments | ask | show | jobs | submit login

This is the weakest or least well-defined aspect of 12factor.

How can you 'store' anything in something as ephemeral as environment variables? Where do these environment variables come from? When are they set?

You should of course store everything in version control; the point of this guideline is that the scope should not be the same as the app or an instance.

There is particular tension between this guideline and X. environments should be a similar as possible and I. there should be a single codebase for all deployments.




Another option is rather than storing configuration in config files, is to store it in code. After experimenting with different approaches, storing configuration in code and switching on a single environment variable ENV (or STAGE or whatever you like to call it) this is probably my favourite.

This doesn't work for everyones infrastructure setups, but it's worked well for mine.


A file that stores configuration is a configuration file, even if the encoding format happens to be the same as the main programming language and not toml or yaml :)

That works fine if there's a limited number of environments, but it becomes a pain if you're running the same app in too many, or if someone else needs to deploy it independently of the developers.


it becomes a pain if you're running the same app in too many,

No it doesn't. It's trivial to generate the full set of configs using a script, if you have too many to manage manually.

or if someone else needs to deploy it independently of the developers

And how exactly do envvars help with that? The set of envvars still needs to get pushed with each deployment. envvars are just a special config file.


Convenient enough for dynamic languages. Not so much compiled ones.


Also ... it's a bit circuitous.

> requires strict separation of config from code. Config varies substantially across deploys, code does not.

What's the difference between config and code? Config is that which changes between deployments / environments.


Config also benefits from review and version control, and it's inconvenient to use multiple systems for these. It's been working out well for us to store secrets encrypted with public key crypto alongside source, or in a deployment repository using the same source control. The private key is inserted into the infrastructure as a K8s secret.


One of the concepts twelve factor pushes is that you should be able to release your source code right now without compromising any credentials.

Basically, you'd have a git repo for code, and a separate git repo for environment scripts. I've seen organizations use a whole separate infrastructure for config, but that always seemed like overkill to me.


This is true with encrypted credentials, if security is compromised by release of the repo then the encryption is not secure. I think the spirit of the principle is met, and in cases where you do later release the source code without having planned for it, it's easy enough to move the secrets.

It's definitely more convenient to use the same repo, especially in the declarative containerized world; you can make sweeping changes or roll them back in a single atomic commit.

That said, if open source is the intent, certainly use multiple repos from the beginning so you avoid git gardening when releasing later.


>How can you 'store' anything in something as ephemeral as environment variables? Where do these environment variables come from? When are they set?

Set at build time. They come from a build config file/script as part of the build. They're not perfect, but just about every tool ever made has a way of understanding environment variables - the same can't be said for any given config file.

Here's a real world example: I want one source of truth for my build configuration, but my build itself pulls together libraries and binaries in a number of different languages and build systems. How would you handle that with anything but environment variables and a master shell script?


> They come from a build config file/script as part of the build.

But the script is in VC surely?

> How would you handle that with anything but environment variables and a master shell script?

Again, where is that master shell script? What args do you give it?

My preference is that you have one environment variable, and your config is keyed off that.

If that environment variable is not supplied, fail noisily.


Kubernetes assists with this aspect of passing environment variables to immutable containers. There you add the variables to the deployment code or edit them live on active deployments.

You can take it one step further and define a single ConfigMap resource per environment, containing all of the required variables across your application, and then have all the various containers reference it ‘blindly’ when they are deployed. Said configuration resource would exist in version control but deploy independently from the functional codebase(s).


Configuration isn't stored in environment variables. Rather, they are exposed as environment variables.

The idea is that the application environment / infrastructure should own the config data, not the application code itself. 12 factor practices require that devs draw a boundary between app and infrastructure.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: