Sunday 31 May 2020

Twelve Factor App - Configuration


The concept of the Twelve Factor app was developed by engineers at Heroku to describe the core principles and qualities that they believe are key to the adoption of the Software as a Service (SaaS) methodology.

First published in 2011 the Heroku platform is unashamedly opinionated in the enforcement of these principles, the relevance of them to effective software development has only intensified as the adoption of cloud computing has increased the number of us deploying and managing server side software.

The third principle relates to the management of configuration within an environment:

"Configuration that varies between deployments should be stored in the environment."

Separate Configuration From Code

All applications will have configuration to control its operation. This will range from database connection strings to credentials for accessing a backing service and smaller items that might influence the look and feel of the UI.

Sometimes it can be tempting to simply define these values in the source code as constants. Whilst this maybe the easiest approach it comes with several disadvantages, some configuration items are sensitive in nature but are exposed to anyone that has access to the code base, plus, when these items need to vary with the environment being deployed into then we now have to deploy different source code in order to change the configuration. 

Some of these issues can be addressed by separating configuration into separate files within the repository. While this may mean that we no longer need to modify source to change the configuration of an environment we do still have to maintain a different deployment process per environment based on files in the repository, and secrets are still available to anyone with access.

Using Environment Variables

The next iteration of separating configuration from code is to make configuration part of the environment the code is being deployed into, completely removing it from the files associated with the deployment.

This can be achieved by using environment variables,  the code once deployed reaching out to the environment to get its required configuration values when they are needed.  

This approach creates a very clean separation between the code and the configuration and isolates the code from any changes between environments. We deploy exactly the same code into each environment from a developer debugging the application locally to our final deployment into our production environment.

Also, because we can separate the process of setting the environment variables from the deployment of the code we can have tighter controls on who can see and set secret configuration values.

Moving Away From Bundling

The use of environment variables has an addtional benefit in that it gives us the chance to move away from the bundling or batching of configuration per environment

While this approach works in most situations it can present a scaling problem if you need many environment or you need to be able to create new environment quickly. With the traditional file based configuration approach an appropriately named file is required per environment.

A more scalable approach is to group configuration values based on the role they perform in the environment, these more granularly sets of values can be combined in the environment to produce an overall configuration.

All developers will have encountered problems and bugs caused by a configuration mishap. These can be unavoidable due to the often complex nature of a reasonably large application. Even by moving configuration into the environment you are unlikely to completely remove the possibility for a mistake to creep in. However, simplifying the approach and completely removing it from the applications source code is certainly a step in the right direction. 


No comments:

Post a Comment