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. 


Sunday 24 May 2020

Twelve Factor App - Dependencies


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 second principle relates to the declaration and management of dependencies:

"All dependencies should be declared, with no implicit reliance on system tools or libraries." 

Code Dependencies

Virtually all software has dependencies, this will range from your particular language and technology platform of choice to the libraries you consume for functionality that is not practical or not expedient for you to write yourselves.

For this reason most programming environments provide some sort of dependency management tooling. .NET as NuGet, Ruby as Gems and Swift as CocoaPods to name a few. Some of these tools provide the option to install packages locally for use within the codebase or more widely as system packages.

The declaration and installation of dependencies should always be explicit and clearly identified, there should never be an implicit reliance on the system to provide a dependency that could cause a runtime issue if for whatever reason it is found to be missing.

Aside from the clear declaration of any dependency, its use within the codebase should be as equally well signposted and clear for developers to see. This can be achieved by following normal good coding practices such as ensuring class dependencies are declared in constructors and using dependency injection to avoid a class creating its own dependencies internally.

System Dependencies

It can be challenging to completely avoid having a reliance on the underlying system on which your software will run. As with the code dependencies we've previously discussed it is important that these dependencies are clearly stated and managed. It should not be the case that the existence of a system dependency is assumed. A common scenario for this issue to make itself apparent is if the software in question invokes the shell to run commands, for example running Curl commands or manipulating the file system.

These kinds of dependencies should either be fulfilled by using the appropriate areas of your technology stack, by vendoring the necessary packages into your application or by using technologies such as Docker to ensure that the necessary dependencies are installed on the system as part of the deployment of your software.

The more your software has a dependency on the system it is running on the less portable it becomes and the more challenges you will have if you need to change or adapt your deployment strategy.

Self Explanatory Application

The aim of this principle is to ensure your software is self explanatory. By this we mean that a developer can gain all the knowledge they need to run and work on your application simply by looking at its repository.

An application that is self explanatory is also agile in nature. This agility manifests itself both in the effectiveness of the teams working on the software and in the options that become available for hosting and deployment.

Dependencies are virtually impossible to avoid, but all developers will have war stories of a vexing issue they've had to deal with that has boiled down to an unclear or complicated interaction with a dependency. 

No strategy is likely to avoid these kinds of issues permanently but recognising that dependencies are a potential source of pain and doing all we can to mitigate them is a sensible approach to take.


Sunday 17 May 2020

Twelve Factor App - Source Code


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 first principle relates to the management of the applications source code:

"There should be exactly one codebase for a deployed service with the codebase being used for many deployments"

Source Code Management

Very few if any teams would now debate the need for source control. Even if you are coding as a lone range the ability to properly organise and manage updates to source code is fundamental to engineering software as opposed to simply coding for fun.

A twelve factor app is contained in a single repository and deployed multiple times.

Whilst there is now very little, if any, debate on the need for source control there are still practices that should be followed to maximise the benefits. These include but aren't limited to:


  • An effective branching strategy to properly separate day to day development from release activity.
  • Using source control features such as git's commit squashing to ensure a clean and readable history of key code base changes.
  • The ability to revert and re-deploy changes when their introduction cause unintended and undesirable consequences.


Self Contained Repository

The repository for your application should contain everything that is required to build and run your application. If your application is actually multiple applications masquerading as a single entity then each distinct application should itself be written as a twelve factor app. 

The first of the twelve factor principles actually states that applications sharing code, at a source code level, is undesirable and instead should be based on libraries using a dependency management solution. This is in contrast to the monolithic repository approach that has gained popularity over recent years.

My personal feeling is that the essence of the principle can still be achieved whilst also benefiting from a monolithic repository. It is still the case that cloning a single repo gives you everything you need to build, run and deploy an application. Being able to view the source of all your internally written dependencies provides a great deal of insight into how your code base works, and still allows a single code base to be deployed multiple times.

Many Deployments

There are many reasons why you may need to deploy your application multiple times. It could be that the application provides functionality needed by multiple aspects of your system, or in a cloud computing world your application may be deployed multiple times as your application scales up or out.

For this process to be efficient all deployments should be using the same code base and deployment mechanism. That is to say that the code base shouldn't require modification based on the environment or context it is being deployed into.

If this isn't the case it makes the predicability of the impact of changes harder to gauge and will lead to instability if the differences between deployments is not properly understood by all members of the team.

The first of the twelve factor principles may now seem so fundamental to good software development as to be an obvious mandate. It's fundamental nature means it provides the required under-pinning to build a solid foundation for the principles to come. It is also never a bad thing to be reminded of fundamentals that may seem like common sense but can easily be forgotten.

Source code makes up the building blocks of any application and so it isn't surprising that an effective strategy for the development of good software would start with the principles that should govern the management of this essential commodity.