The missing factor in 12 factor apps
If you haven’t heard of this yet, 12 Factor apps concept was synthesized at Heroku, a PaaS platform. The 12 factors came in to existence from experience of teams working on Heroku to develop, deploy and manage thousands of apps on that platform. It’s a great mechanism for development teams to write standardized PaaS apps using best practice principles consistently across the apps. All the benefits that you would get by virtue of standardization like ease of maintenance ease for troubleshooting ease of ramping up new teams and ease of deploying apps across different environment, you would get by way of following 12 factor apps principles. This really fits well with overall DevOps push and cloud application deployments, especially if you are developing for PaaS and you would like to maintain reasonable level of interoperability across different PaaS platforms.
Here is a summary of explanation and benefit in plain English for each of the factors –
- Codebase - One codebase tracked in revision control, many deploys
This is one of the non-negotiable and self-explanatory, fundamental requirement.
- Dependencies - Explicitly declare and isolate dependencies
These are external dependencies like specific libraries you have in your application. Your build and deploy scripts should exactly know versions and repositories to get these from. This is one of the very high Importance factors.
III. Config - Store config in the environment
This is related to making sure you externalize configurations of your app. This helps in enabling teams to achieve ‘Build once deploy on any environment’ goal. If not understood correctly, this can setup wrong expectations and be very deceptive, more to come on this later.
- Backing services - Treat backing services as attached resources
This encourages loose coupling between your application and services it depends on, for example database. Best practice here is to invoke services you are dependent on using simple end point like an URL. This hides complexity, reduces coupling and promotes flexibility for change.
- Build, release, run - Strictly separate build and run stages
The idea here is to make run stage as simple as possible and push complexities of building the apps towards development teams. This helps in making sure run stage has less moving parts and in case of runtime issues, operations teams are able to recover faster with lower dependencies on development teams.
- Processes - Execute the app as one or more stateless processes
This factor promotes stateless, independent processes. This is needed for achieving scalability and independent operation of various components. Session stickiness is against this principle. Development teams should avoid using sticky sessions. Sticky sessions adversely impacts ability of your app to scale.
VII. Port binding - Export services via port binding
This is extension of factor IV above. This is encouraging teams to expose your application and application services (APIs) using endpoints and port bindings. This factor promotes flexibility, loose coupling and scalability of your application.
VIII. Concurrency - Scale out via the process model
This is very important factor for achieving scalability. You should write, package and deploy your applications in such a way that you have different components of the app deployed and running as different, independent processes. Allows for upscaling and downscaling of components independent of each other.
- Disposability - Maximize robustness with fast startup and graceful shutdown
This factor relates to overall improvement of uptimes during restarts done for maintenance and after application crashes. Your app should not be performing heavy processing during startup and shutdown.
- Dev/prod parity - Keep development, staging, and production as similar as possible
This is Self-explanatory factor. This helps in reducing possibility of surprises as you promote your app through various environments. This factor improves ability of teams to troubleshoot production issues.
- Logs - Treat logs as event streams
This is important factor in helping development/support teams to troubleshoot and monitor overall health of the apps. This factor needs tooling like Splunk Storm; New Relic attached with analytics tools to provide right level of insights in to application logs.
XII. Admin processes - Run admin/management tasks as one-off processes
This factor talks to the need of application tools to run one off admin tasks on the apps. Example of one off tasks includes, but not limited to, one of data cleanup, turning on or off features at run time. This factor promotes creating tooling to support admin tasks.
All great things, right? However, I do have issue with factor III -
“Config - Store config in the environment.”
This factor can be very misleading and deceptive if not understood correctly. This factor promotes interoperability by externalizing configurations. However, we need to understand that externalizing configurations is only the first step in achieving true interoperability. Even if we externalize the configuration, for example configuration related to DB access, your app has implicit awareness of the environment it’s running in. True interoperability can be achieved only when your app does not need to be aware of the environment it’s running in.
One way this can be achieved by containerizing your app. Your app container has everything that your app needs to run. However, containerizing your app does come at a price.
Please do not get me wrong, I am whole heatedly for using 12 factor app as guiding principle for writing PaaS apps. Every team writing applications for PaaS platform should use it. However, just be fully aware that you will not get 100% interoperability by just following 12 Factor apps. Full interoperability comes at a cost. That cost may be incurred in the form of the changes to the application or moving fully to containerized solution like Docker.
In summary, 12 factor app is a great way to develop, deploy and manage your apps and has many benefits. However if your goal is true interoperability across many platforms, in addition to the 12 factors, you may have to consider containerizing your app.
Reference –
Prashant, agree with you about the benefits of containers. The 'Container' is a building block of most PAAS platforms, so it is kind of assumed that you will 'containerize' your application when you move to PAAS.