Twelve-Factor Apps: A Retrospective and Look Forward

DZone 's Guide to

Twelve-Factor Apps: A Retrospective and Look Forward

Cloud applications continue to be developed using this popular framework to ensure they remain scalable and cloud-optimized.

· DevOps Zone ·
Free Resource

Image title

If your team is creating apps for the cloud, chances are the Twelve-Factor App methodology has influenced the frameworks and platforms you’re using. Popular frameworks such as Spring Boot, Magento, and more credit the twelve factors as part of their design. Leading companies such as Heroku, Amazon, and Microsoft use and recommend the methodology. While new frameworks and methodologies are released every month, few have the far-reaching impact of this one.

Let's take a look at what these factors are all about, the story behind the creation of this methodology seven years ago, and why they are just as important today.

Creation of Twelve-Factor Apps

In late 2011, Heroku co-founder Adam Wiggins knew there was a problem with the state of application development and deployment. Adam and his team had been personally involved in hundreds of apps and witnessed hundreds of thousands of app deployments into the cloud through the Heroku platform. Some of these apps were successful, taking advantage of features such as distributed architectures. But some of these apps had serious problems: they were not scalable, portable, or easy to maintain. The team recognized a common set of issues among these problem apps, and wanted to do something about it.

Adam and his team came up with a set of guidelines for building successful cloud apps—guidelines that would minimize cost and time, maximize portability, enable continuous deployment, and scale up without changes to processes or architecture.

Twelve-Factor Apps: A Methodology for SaaS App Development

Let’s start with an overview of the twelve factors. You can see the full list and extra detail for each factor at 12factor.net.

  1. Codebase: Use source control. One codebase per application. Deploy to multiple environments.
  2. Dependencies: Declare and isolate dependencies. Never rely on the existence of system packages. Never commit dependencies in the codebase repository.
  3. Config: Keep configuration separate from the codebase.
  4. Backing Services: Treat services the app consumes (database, caching, and so on) as attachable resources. You should be able to swap your database instance without code changes.
  5. Build, Release, Run: Deploy apps in three discrete steps: build (convert codebase into executable), release (combine build artifacts with config to create a release image), and run (use the same release image every time you launch).
  6. Processes: Processes should be stateless.
  7. Port Binding: Export services via port binding. Apps should be completely self-contained.
  8. Concurrency: Scale out by decomposing applications into individual processes that do specific jobs.
  9. Disposability: Apps should be quick to start, resilient to failure, and graceful to shut down. Expect servers to fail, be added, change.
  10. Dev/prod parity: Keep the development environment identical to all other environments.
  11. Logs: Treat logs as events streams. Write to stdout and stderr.
  12. Admin Processes: Run admin tasks (database migrations, background jobs, cache clearing, and so on) as one-off, isolated processes.

How the Twelve-Factor App Changed Application Development and DevOps

Over the past seven years, these twelve factors have guided tens of thousands of apps to success. In fact, the methodology has worked so well in creating apps that are maintainable, scalable, and portable that many of the twelve factors have now been adopted as “common sense” for cloud development and DevOps. We all now know about explicit dependency declarations, scaling out versus up, and the benefits of a code repository. However, some of these factors were radical suggestions when first introduced.

These battle-tested, industry-accepted factors have even been codified by some of the most successful cloud frameworks and tools. Most modern frameworks such as Spring and Spring Boot, Symfony, and Magento (Adobe) embody the twelve factors as part of their design principles. Tools such as Docker images and Heroku slugs (build/release/run), Vagrant (dev/prod parity), Puppet and Vault (configuration), and Papertrail (logging) have been created to enforce, automate, and simplify management for apps using the factors.

The Heroku platform itself is an embodiment of the twelve factors. For example, Heroku requires apps to be decomposed into one or more lightweight, discrete containers (dynos)—a direct manifestation of the stateless factor. Heroku also enforces languages and frameworks to use an explicit list of app dependencies (such as Ruby’s bundler), allows admin processes to be run in isolation using one-off dynos, and aggregates the output streams of all running dynos in an application so that logs can be processed as a stream.

Just As Important Today As Seven Years Ago

The Twelve-Factor App methodology continues to be just as important today as when it was first released. Millions of people visited the Twelve-Factor App website in the last year. Companies such as Amazon, Microsoft, IBM and Pivotal continue to use and recommend the methodology.

Newer architectures, such as microservices, serverless containers, and most cloud deployment still benefit from (and often critically enforce) the methodology. Amazon Lambda functions, for example, enforce factors such as stateless components, scaling out, disposability, isolated admin functions, and backing services.

The Twelve-Factor App methodology has guided an enormous number of apps, frameworks, and platforms to success over the years. Taking these factors into consideration early in your design process will help you and your team architect scalable, portable, maintainable apps.

design patterns ,devops ,software architecture ,webapps

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}