Ever heard of the twelve-factor app?
The complexity of software applications continues to grow exponentially amongst organisations around the world and it is increasingly critical that organisations find ways to efficiently build, manage and maintain these complexities to stay competitive. To help with this is the concept of the twelve-factor app. In this article, we will briefly look at the ideas behind this concept and also review a few AWS-specific technologies that help us implement them as well. At the end of this article, I will also share some useful resources to help understand these concepts in much more detail so make sure you read to the end.
The 12-factor app is a methodology for building scalable and maintainable applications that run in the cloud. It was first introduced by Heroku, a cloud platform as a service (PaaS) provider, in 2011. The methodology consists of a set of best practices that help developers build cloud-native applications that can be easily deployed and scaled. The 12 factors are designed to address issues that can arise when building applications that need to operate at scale, and they cover a range of topics, including configuration management, deployment, and scaling.
The 12 factors and some AWS services that can help you implement these principles:
Codebase: One codebase tracked in revision control, many deploys.
This factor emphasizes the importance of version control for your codebase. It suggests that you should have one codebase, which is version-controlled, and use it for all your deployments, rather than creating separate codebases for each deployment.
AWS CodeCommit is a fully managed source control service that makes hosting secure and highly scalable private Git repositories easy. You can use it to manage your application code and keep it in a central location.
Dependencies: Explicitly declare and isolate dependencies.
This factor emphasizes the importance of managing dependencies and keeping them isolated from the rest of the system. It suggests using a package manager to explicitly declare and manage dependencies.
Configuration: Store configuration in the environment.
This factor emphasizes the importance of storing configuration variables as environment variables, rather than hardcoding them in your code. This makes it easier to change configuration variables without having to change the code itself.
AWS Systems Manager Parameter Store is a managed service that stores and retrieves application configuration data. You can use it to store environment-specific variables, secrets, and other configuration parameters.
Backing services: Treat backing services as attached resources. This factor emphasizes the importance of treating backing services (databases, queues, caches, etc.) as attached resources, rather than bundled with the application. This makes it easier to manage and scale these services independently.
Build, release, run: Strictly separate build and run stages.
This factor emphasizes the importance of separating the build, release, and run stages of your application. It suggests that you should build your application in one stage, release it in another, and then run it in yet another.
AWS CodePipeline is a fully managed continuous delivery service that automates your software release process. It integrates with other AWS services like CodeCommit, CodeBuild, and CodeDeploy to build, test, and deploy your application code.
Processes: Execute the app as one or more stateless processes.
This factor emphasizes the importance of treating your application as a collection of stateless processes, rather than a monolithic application. This makes it easier to scale and maintain your application.
Apps and services should be stateless, with any state residing in a backing store. This is an important prerequisite for other Twelve-Factor guidelines, such as concurrency and disposability. One AWS service that can help you implement the Processes factor is AWS Fargate. Fargate is a serverless compute engine for containers that allows you to run Docker containers without having to manage servers or clusters. By using Fargate to run your application in stateless containers, you can achieve high availability and scalability, while ensuring that each container is independent and can be easily replaced or scaled out. This helps you build cloud-native applications that are easy to deploy, manage, and scale.
Port binding: Export services via port binding.
This factor emphasizes the importance of exporting services via port binding, rather than hardcoding service locations. This makes it easier to scale your application and ensures that services are always available at the same location.
AWS Elastic Load Balancing automatically distributes incoming application traffic across multiple targets, such as EC2 instances or containers, in a single Availability Zone or across multiple Availability Zones. ELB can also help you manage port assignments for your application. When you configure your load balancer, you specify a target group that contains the instances of your application that should receive traffic. You can also specify the port number that your application listens on, and ELB will map that port number to a host port.
Concurrency: Scale out via the process model.
This factor emphasizes the importance of scaling your application horizontally, by adding more processes, rather than vertically, by adding more resources to a single process. This makes it easier to scale your application and ensures that it remains highly available.
AWS Auto Scaling automatically adjusts the capacity of your application based on demand. You can use it to scale up or down the number of EC2 instances or containers based on CPU utilization, network traffic, or other metrics.
Disposability: Maximize robustness with fast startup and graceful shutdown. This factor emphasizes the importance of ensuring that your application can start up quickly and shut down gracefully. This makes it easier to handle failures and ensures that your application remains highly available.
AWS Lambda is a serverless compute service that allows you to run code without provisioning or managing servers. It provides automatic scaling, high availability, and fault tolerance out of the box.
Dev/prod parity: Keep development, staging, and production as similar as possible.
This factor emphasizes the importance of keeping your development, staging, and production environments as similar as possible. This makes it easier to identify and fix issues in your application.
AWS CloudFormation allows you to define and deploy infrastructure as code. You can use it to create identical copies of your infrastructure in development, staging, and production environments.
Logs: Treat logs as event streams.
This factor emphasizes the importance of treating your application logs as event streams, rather than static files. This makes it easier to analyze and troubleshoot issues in your application.
AWS CloudWatch Logs is a fully managed service that makes it easy to collect, monitor, and analyze log data from your applications and systems. You can use it to troubleshoot issues, identify trends, and improve performance.
Admin processes: Run admin/management tasks as one-off processes.
This factor emphasizes the importance of running administrative and management tasks as one-off processes, rather than bundling them with the application. This makes it easier to manage these tasks and ensures that they don't impact the performance of the application.
AWS Systems Manager for managing and automating tasks on EC2 instances.
The 12-factor app is an interesting subject and acts as a guide to help developers and software architects rethink their strategies for building scalable, modern SaaS applications. In this article, we briefly outlined what these 12 factors are and looked at some specific AWS services that can help us build solutions with the 12 factor in mind.
It might be worth looking at the official 12-factor website for a more detailed explanation of these factors https://12factor.net/