Skip to content

12 Factor App Configuration Rebuttal

Jeff Felchner edited this page Jan 12, 2018 · 1 revision

The common reason why a lot of the current configuration libraries are designed the way they are, is because of the 12-Factor App manifesto.

While I agree with a lot of what is written in there, the configuration section is, in my opinion, way off base. Especially when compared to how developers and development teams actually work in the real world.

What Are 12-Factor Applications?

"12-Factor Applications" is a term coined by Adam Wiggins who was a co-founder of Heroku. You can find the original source of the 12-Factor manifesto here.

While broken up into multiple sections, the section we're going to focus on here is the Config portion. And specifically:

Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code. Config varies substantially across deploys, code does not.

A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials.

...snip...

...it's easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific.

Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle.

The Rebuttal

Let's take this piece-by-piece and describe how using Chamber makes these a non-issue:

Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code.

Despite the fact that this is a logical fallacy, Chamber does allow you to store all your settings in a separate repository, but the entire point of it is that you don't have to.

Config varies substantially across deploys, code does not.

Let's just, for the sake of argument, assume that this is true, that still doesn't then mean that environment variables are the best way of dealing with this fact.

A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials.

Due to Chamber's encryption, you can absolutely do this.

...it's easy to mistakenly check in a config file to the repo

With Chamber, this doesn't matter. And as far as accidentally committing settings to the repository which should be secret? Our commit hook solves that problem.

there is a tendency for config files to be scattered about in different places and different formats making it hard to see and manage all the config in one place.

This is especially true if you have to store your settings in a separate repo, or you have some settings in a share somewhere, or you have a mess of environment variables on each of your servers with no way to coordinate between all of them.

Chamber gives you one place for all your settings and it's right alongside your application code. There's no need to manage shares or separate repositories. All Chamber settings are in YAML format keeping things consistent.

Further, these formats tend to be language- or framework-specific.

YAML is a cross-platform, cross-language, cross-framework specification.

Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called "environments") named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle.

Yet again, this is true, but storing configuration in the environment doesn't solve this problem. But with YAML's anchoring and references, Chamber does.

In Conclusion

There's absolutely nothing wrong with storing the bulk of your configuration in files that are alongside your code. The only reason it hasn't been done is because secret values needed to stay secret. With Chamber, you can have the best of both worlds.

Clone this wiki locally