7

so I have been building my application mostly as 12 factor app and now looking at the config part.

Right now as it stands I have separate config files for dev and production and through the build process we either build a dev or production image. The code is 100% the same the only thing that changes is the config.

Now I 100% understand that in a 12 factor app the config should come from external source such as: environment variables, or maybe a safe store like vault etc...

So what the various articles and blogs fail to mention about the config is the how is the config stored/processed. If the code is separated in it's own git repo and it has no config stored with it then how do we handle the config?

Do we store the actual config values on a separate git and then some how merge/push/execute those on the target environment (Kubernet config map, marathon JSON config, Vault, etc...) through the build process using some kind of trigger?

user432024
  • 4,392
  • 8
  • 49
  • 85

1 Answers1

5

There is not a standard but what I've been observing is some common behaviors like:

  1. Sensitive information never gets on versioning system, specially git which is a DCVS (you can clone the repo for other locations). If you don't follow, remember that our existing "security system" is based on the incapacity of read crypto info in a certain time, but in certain point you might be able to read the info. Usually on kubernetes I see operators, managing the service account across multiple namespaces and then other only referring the service account, tools like KMS, Cert manager, Vault and etc. are welcome

  2. Configuration like env vars, endpoints, are stored and versioned with their own "lifecycle".

12factor does not meant to separate the configuration of your app from your repository, instead suggest not to put into your app (like on your container or even binary distribution).

In fact if you want to use a separate repo only for config you can do it, but if you want to put aside your project source code the configuration, you can do it as well. It is more a decision based on the size of the project, complexity, segregation of duties and team context. (IMHO)

On my case of study for instance, makes sense to separate config on a dedicated repository as production environment has more than 50 cluster, which one with their own isolation stack, also there are different teams managing their own services and using common backing services (db, api, streams...). In my opinion as long as things gets more complex and cross-shared, makes more sense to separate config on independent repository, as there are several teams and resources over multiple clusters.

gonzalesraul
  • 777
  • 3
  • 14
  • Currently right now, we have buildImageDev and buildImageProd tasks which uses conf-dev.json and conf-prod.json and that lives with the code. Code is 100% the same only the config file name changes. But there have been cases where people have made cut and paste mistakes of copying dev values into prod values. Other option is to do the same as we treat 3rd party applications and use separate repos for holding configs for each one of those apps. Examples: Kafka, Elasticsearch etc... So each of those configs have their own repos. So we can treat our apps that way too. – user432024 Dec 10 '18 at 20:49
  • In that case I would suggest you, on your image spec (dockerfile) describe a VOLUME to put your config file, makes the app (process) read that, otherwise assume default values And during orchestration, mount a configmap by the key on your podSpec, and makes a configmap different for each environment. Optionally if your app supports envvar, try to stick on envvar parametrization over config file, as it might give you a little extra flexibility – gonzalesraul Dec 11 '18 at 00:29
  • Yeah right now I copy the config file into the image. But where would you store all the configmap values, same repo or separate repo? – user432024 Dec 11 '18 at 16:08