Sunday 28 June 2020

Twelve Factor App - Port Binding


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 sixth principle relates to how applications expose their functionality to the wider world or estate:

"Self-contained services should make themselves available to other services by specified ports."

Running Inside a Web Server

It is a common pattern of application development and deployment for an application to be run from within a web server.

In this model the application build process often produces a binary that is itself not executable. During the release phase the application is placed within a web server that provides an environment in which the application can be invoked and the underlying functionality consumed.

This approach means the application isn't able to function independently and is reliable on the web server to turn it into a useful application.

Self Contained Web Server

An important goal of a twelve factor app is to be self contained and not dependent on other software to be useful. Running inside a web server doesn't allow an app to meet these aspirations.

Instead a twelve factor app contains a web server implementation within it. This means when the application is built it is a fully fledged executable without the need for additional software to be used to bring it to life.

An example of this is the Kestrel web server used within .NET Core applications. This lightweight web server is built into a .NET Core application and enables it to provide its functionality as a direct result of the build process with no additional web server being required to host the application.

Using this technique a twelve factor app can expose its functionality by binding a process to a given port. As an example when debugging the application locally it might be accessed by http://localhost:5001/my/cool/api. 

This same approach of a process binding to a port can be-re-used in any environment with different aspects of the application, running as different processed, exposing their functionality on different ports.

Walking on the Edge

Quite often the web server embedded into the application, such as Kestrel, can act as an edge server exposing the application directly to the outside world.

In reality this is unlikely to be the case. There may be security or networking requirements that necessity a bulkier more feature rich web server to be used to act as a reverse proxy onto the application.

The important aspect of this approach is that the application can be developed independent of these requirements, since it is not responsible for their implementation. Because it is a self contained application listening on a port the technology and set-up of the reverse proxying infrastructure can be changed and optimised with no risk that the application will fail to function or will need to be changed to reflect these changes.

Independence is an important quality for any piece of software. The more bonds we have between applications and areas of the code the more the impact of change will ripple through a code base. The twelve factor principles, by the promoting self containment, try to avoid this situation and create an environment where each area of a wider estate can be worked on in isolation. 

This means each area can be optimised and taken in the best direction for the functionality it provides. Many technology platforms recognise this and are giving you the tools you need to make this a reality for your suite of applications.   


Sunday 21 June 2020

Twelve Factor App - Processes



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 sixth principle relates to the process model used within the application:

"Applications should be deployed as one or more stateless processes with persisted data stored on a backing service."

The Process Model

An applications source code and the binary it produces represent the processor instructions that produce the intended functionality. A process is an instance, provided by the devices operating system, of these instructions running against the devices processor. 

At a high level the process is made up of, the applications instructions, allocated memory and threads of execution, handles to file system resources and security attributes such as the user who owns the process etc.

A complex application may be made up of multiple processes each with a particular role providing functionality to the whole. The process model also represents a method of scaling an application by enabling the same functionality to be available multiple times by replica processes running on the same machine.

Stateless Processes

A twelve factor app views application processes as state less sharing nothing between themselves. 

In practice this means that the data the process works with and stores directly should be short lived and assumed to not persist to be available in the future. With many application processes dealing with many incoming requests it is extremely unlikely that the same process will deal with any future request from the same user.

Even if your application was only a single process it is still dangerous to assume that data will always be available when the process or the machine could be restarted or otherwise lose access to the memory space.

This isn't to say that an application cannot store and use data in a process but that it should expect the data to only be available while dealing with the current request and not available for any future requests.

State in Backing Services

A users interaction with an application is usually made up of multiple requests over a period of time. In this situation it is unrealistic to think that some data won't have to persist between these requests in order to give the user a seamless experience.

Twelve factor principles don't forbid this but they do state that the process is not a good place to store this data.

Instead a backing service, available to all application processes and independent of any process lifecycle should be used to hold the necessary user session state. Because this data is often needed to be available and updated quickly caching services such as Redis are good candidates to provides this data storage.

Many of the twelve factor principles promote behaviours and approaches that benefit scaling of an application. Relying on session sticky-ness reduces the ability of an application to scale as resources need to be reserved in order to deal with possible future requests, or fail or take longer to complete because of missing data. Writing your application to not rely on sticky-ness means you can make more efficient use of your available resources in order to ensure you can deal with the maximum number of request possible.

Integrating with backing services that can provide the necessary data storage without being tied to an application process is a relatively easy way to follow this principle and produce an efficient productive application.

Sunday 14 June 2020

Twelve Factor App - Build, Release and Run


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 fourth principle relates to the strict separation of the build, release and run phases of application development:

"The delivery pipeline should strictly consist of build, release, run."

Development to Deployment

A codebase is transformed from source code to a working application in three stages.

The Build stage converts source code into an executable binary. The resultant binary is a combination of source code produced by the development team, 3rd party dependencies and the underlying framework being used to produce the application.

The Release stage takes the binary and combines this with configuration suitable for the environment that it will be deployed into. 

Finally the Run stage starts the application in the environment, bringing it to life and making the functionality it provides available to the rest of the estate.

The exact nature of all of these stages will vary greatly depending on the technologies being used during development but the essence of the three distinct stages remains. Build your code, combine it with configuration and deploy, then finally run your code in the environment.

An app following the twelve factor principles strives to maintain this strict separation.

Isolation of Change

The first important aspect of maintaining this separation is to isolate where functional changes can be made. As an example functional changes to the application should not be made as part of the run phase. Any such changes cannot be pushed upstream to the build phase and therefore create inconsistency during development and testing.

It maybe that configuration changes made during the release phase can also affect functionality but these changes can be easily applied during development in a consistent and controlled manner.

By properly isolating change we increase the repeatability of the entire process to produce consistent results, not only in a production environment but for local and shared development environments as well.

Always Releasing

Release and run and phases should be as simple and quick as possible. Not only is this a desirable quality for any piece of engineering but in a modern cloud based architecture deployment is a frequently occurring operation.

As an environment scales out with more copies of your application being required a reliable and fast deployment mechanism is essential in being able to respond to demand.

A slick and fast deployment process also reduces the amount of time it takes from developer commit to running in production. The compound effect of these marginal gains enables consistent gains and improvements in your applications performance and effectiveness.

Finally an effective release process also enables strong rollback strategies when a change into production needs to be reversed. The more complicated the release process the more any rollback is a leap into the unknown and the less likely that the environment can be returned to a working state quickly.

The need to keep these three phases separate may on the face of it seem obvious but inefficiencies and sub-optimal changes can easily cause the line between them to be blurred over time. Recognising the impact this has and being on the look out for anything that goes against this goal is key to maintaining a healthy development environment. As with most aspects of software engineering this is more of a goal than an absolute but being driven by the correct principles will never normally steer you wrong.    


Sunday 7 June 2020

Twelve Factor App - Backing Services



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 backing services:

"All backing services are treated as attached resources and attached and detached by the execution environment."

Backing Services

Applications will routinely need to consume resources that are not part of the code being deployed. These might be databases, queuing system or communication services such as the sending of email or push messages.

The management and the deployment of these services will likely be a mixture of those being supplied by the same team that are deploying the application and those that our sourced from third parties.

These services are often also drivers of change, either because of a change in supplier or because the team wants to move to a new technology. Generally these services also need to be highly available with outages not being tolerable.

Attached Resources

If an app is written to follow twelve factor principles then it will treat all backing services as attached resources accessible via a URL defined by the configuration within the environment.

The goal of this approach is to the limit the impact of needing to change the source of the functionality. If we have written custom code to interact with a resource or we are using a proprietary SDK then any change in the technology being used will mean code changes and a new deployment of the application is required.

By accessing the resource via a URL, provided by the environment, then in theory we can change the location and technology of these services without the need for any code changes.

Minimal Changes

In practice this will often be difficult to achieve, if for example we change to a different database technology this might require at least tweaks to our code if the feature sets have some variation. 

However by making efforts to push the functionality provided by the services to the edge of our application we have done everything we can to avoid unnecessary change.

It is often a marker for good software architecture for there to be identifiable seams in the code that enable these kinds of changes to be achieved with minimal overall change in the structure of the code. I think this a more realistic aim than hoping to never need to make code changes when a service changes.

An application is hardly ever able to contain all the functionality that's required to achieve the overall aim, it will always be the case that the code will need to interact with external services. Ensuring the nature of these services is not hard baked into the code needs to be a top priority not just to allow for future changes but also to ensure a clean overall architecture.