12-Factors in Microservices / App
What is 12-Factors?
- It is a methodology of best practices, and can be used by any developer for making or scaling the application Software-as-a-Service (SaaS) app.
- It can be applied to development of any app or microservice.
- This methodology is language independent.
- It is independent of platforms with respect to in-premises or cloud.
1. Single Codebase
(Manage under single codebase and many deployments)
- For any app/microservice, there should be one and only one codebase.
- Each developer in the team can have the same code base in their local machine but it should belong to one common root.
- No 2 Apps should share the same code base, as, one app can not have code from two code bases.
- The concept of a single codebase can be managed using code-repositories/sub-versioning tools like Git, SVN, CVS.
- There should be only one codebase, but it can have multiple versions and multiple deployments in different environments.
- Example — as if there are 4 environments like dev, test, stage, and prod. All 4 environments can have different versions of code but they should be from the same code base.
2. Dependencies
(Declare and Isolate)
- For any application, dependencies should be declared and isolated very clearly.
- 12-factor microservice should never rely on implicit dependency.
- In different languages, different manifest tools help to declare the dependencies.
- For example, In Java, Maven can be used to define the dependencies. In maven, XML file known as Project Object Model (POM) file is used for dependencies declaration.
- In Python, pip, and virtualenv are used for dependency declaration and isolation respectively.
3. Config
(Store configs in the environment)
•Every microservice should have a clear separation of code and config. Variables that are not dependent on code logic and can be changed without touching the code should be kept in the configuration files.
•In a clear separation between code and config, every microservice has a lot of configuration.
•Some configuration remains the same while some differ during the deployments in different environments (For dev, test, stage, or prod).
•Configurations that vary (e.g. DB credentials, port, hostname, etc), should be externalized and should not be saved in any constants. That will be a violation of the 12-factor app.
•Now let’s learn further how to manage the configs which remain the same
- Configs that remain the same can be defined in the files and can be committed along with the code.
- In some applications, editing rights to the code branch are for limited developers as they don’t require many changes.
•The config’s which varies,
- In these kinds of configs, there are different ways to handle it.
- If these configs are saved as other configs, either developer is instructed not to commit any changes or commit rights can be restricted up to admin only.
- Values can be saved in a persistent database and can be fetched from DB when needed as per the environment’s need.
- Values can be saved along with the environment variables in windows kind of OS.
4. Backing Services
(Treat backing services as attached resources)
- Any service that microservice consumes for its operation is known as backing service.
- In a 12-factor app or microservice, backing services should be treated as resources. Examples like Database, SMTP Service, Identity Service, Amazon S3.
- Backing services’ details must be kept in the configuration files. So in case of any issue, one resource can be replaced by another compatible resource without making any changes in the codebase.
- 12-factor app or microservice does not distinguish between local or third party backing service, all the backing services are treated equally as resources.
- All the resources must be accessed via a URL or Credentials and must be loosely coupled.
5. Build, Release, Run
(Treat as separate stages — Build, Release, Run stages)
- According to 12 factors, each service must have these 3 separate stages
- Build — it is a stage when codebase from a repository turns into an executable bundle (jar/war) file.
- Release — It is a stage with an executable file is combined with the config files and ready for the execution in the required environment.
- Run — This stage, when the application is running in the appropriate environment and available for its customers.
- Above mentioned are 3 various stages when code from the repository goes into a running environment. There are different tools available in today’s world to handle these stages separately but there are other tools like Jenkins also available which makes the developer’s life very easy and segregate these stages from each other.
- Every build and release should have unique names, so when the situation arises, it is easy to roll back the build to the previous release.
6. Processes
(Application should be executed as one/more stateless)
- As per 12 factors, the application must be stateless.
- If any stateful data needs to be shared between instances, it has to be done in backing service.
7. Port Binding
(Export service via port binding)
- 12-factor service or app is completely self-contained and does not rely on any runtime injection of any web server whereas mostly web applications require a web server and a port to run.
- 12-factor service or app requires only a run time environment for their execution.
8. Concurrency
(Scale the application using process model)
- Concurrency is the ability of a process to run several programs in parallel to carry out a task. These parallel programs are known as threads and, threads have immense capability to increase or scale the throughput.
- In 12-Factor methodology, services are suggested to rely on processes for scaling. Where a process can internally adapt to the multithreading model.
9. Disposability
(Handle start and stop activity with grace)
- A 12-Factor service is supposed to handle disposability with grace.
- With grace, it means, if there is a need to start or stop the application for any reason, the application should be able to start or stop without any side effects and within the SLA.
- Disposability provides the flexibility to start, stop, or restart the application at any time without any surprising outcomes.
10. Dev/Prod Parity
(Keep all the environment identical)
- As per this rule, all the environments used for service/app deployment should be similar.
- Environments that includes all the backing services must be similar.
- This rule is to avoid any issue or surprise in production. If code works in dev environment then it will work in any other environment as well having similar backing services.
- To be complaint to this rule, it is recommended to use the containers.
11. Logs
(Treat logs as event stream)
- In a 12-factor service/app, logs should be captured as event streams.
- The service shouldn’t be worried about capturing logs in the file or how the storage is going to be managed for keeping the logs. Instead, logs should be written as stdout and can be analysed and indexed using tools of log streams like splunk.
- Past logs should be archived using the hive tools.
12. Admin Processes
(Run admin/management tasks as one-off processes)
•In an application/service, there is often a need of performing one-off process or task. These processes are called Admin Processes. They could be similar to followings:
- Performing one time database upload
- Extract adhoc report
- Database migration
- Fixing the data
•There should be scripts to perform the admin processes and should be kept along with the codebase.
•Script for the admin processes should also be executed in the identical environment as code base to avoid any issue.