DEV Community

loading...

Why and what you should do to follow Beyond the Twelve-Factor App

Kazuro Fukuhara
working at GMO Research
・7 min read

What is this document?

I think Beyond the Twelve-Factor App 1 is a good document, but I also think the purpose and reason for each item is not clear.
This may go without saying, but I think it would be unsettling if it were not clear.

Beyond the Twelve-Factor App has the following 15 items. In order of priority.

  1. One codebase, one application
  2. API first
  3. Dependency management
  4. Design, build, release, and run
  5. Configuration, credentials, and code
  6. Logs
  7. Disposability
  8. Backing services
  9. Environment parity
  10. Administrative processes
  11. Port binding
  12. Stateless processes
  13. Concurrency
  14. Telemetry
  15. Authentication and authorization

In this document, I have summarized the purpose and tasks of each of them.
Some parts of this document are my own compositions.
I may have misunderstood the intent of the original document due to my lack of understanding or misunderstanding.
I welcome your pointing out the mistakes. 2

Background of the original document

As a precursor to Beyond the Twelve-Factor App, there is a document called The Twelve-Factor App 3.
This is about the methodology for building out Software as a Service, written by the guys at heroku.

Beyond the Twelve-Factor App adds content and details to the original Twelve-Factor App, written by the folks at pivotal.

1. one codebase, one application

What for.

  • I want to automate build and deployment. If an app is split into multiple repositories, it becomes difficult to automate.
  • If multiple apps or multiple teams share one repository, it is more natural to follow Conway's Law 4.

What to do.

Make application and its repositories one-to-one, or one application and multiple repositories that share a common root.

2. API First

What for.

  • I want to have a resource to discuss user stories and features with stakeholders.
  • I want to avoid mistakes when integrating with other systems.

What to do

Make the your API as a first-class artifact of the development process. 5.

3. Dependency Management

What for.

We want to make sure that the application does not depend on the configuration of the running environment. We want to do repeatable deployments easily.

What to do

Define dependency for each application.Make no assumptions about what is installed and what libraries and tools are available in the production environment.

4. Design, Build, Release, Run

What for.

We want to maximize your delivery speed while keeping the developer's high confidence.

What to do

Divide the flow from development to operation into four parts: design, build, release, and run. Each of them should be executed independently. The details are as follows.

Design

Design the next feature to be released.
There is an overall design, but it will change, so it should be done a little at a time in each iteration.
This is also the time to decide which libraries should be used.

Build

Code is converted into binary artifacts (i.e., builds), and CI tools should be used. One build will be released to multiple environments. (Test, QA, production, etc.)
If you have a "it only works in my environment" problem, it means that the four steps in this section are not properly separated.

Release

Release is the process of adding environment-specific and application-specific settings to the build.
Each release should have a unique ID and should be immutable.
It can be used for troubleshooting and rollback.

Run

Once released to the environment, the cloud provider executes it.
The cloud execution environment is responsible for running, health-checking, and logging the app, as well as management tasks for dynamic scaling and fault tolerance.

5. Configuration, Credentials, and Code

What for.

If you put configuration and code under the same management, it became to hard to manage the configuration for each environment. If you put credentials and code under the same management, many developers can see them. It is not desirable.

What to do

Manage configuration, credential, and code separately. The authentication information and configuration should be environment variables, and injected in the build product at the time of release.

6. Logs

What for.

We want to simplify the application by making it does not manage the log information.When the number of app execution environments increases dynamically, a log file is created for each environment. We want to manage/analyze such log information easily.

What to do

Treat the log as event streams. As an application, don't care where it is placed, and just output the log to stdout and stderr. Use another tool or system to collect and analyze the output.

Discussion around

App developers tend to elaborate on the design of log output, but they should stop doing it in the app but only generate log message to stdout.

7. Disposability

What for.

You want to be able to scale, deploy, release, and recover your app quickly.

What to do

Make it easy to discard the execution process. Also, make it possible to start and stop the app quickly. If your application require a lengthy cache initialization process,you should separate it to backing services, if possible.

8. Backing Services

What for.

I want to be able to connect and disconnect services that my app depends on easily and freely. This is useful in case of failures.

What to do

Declare the services that the app depends on (i.e. backing services). Use the cloud environment functions to actually connect them.

9. Environment Parity

What for.

You want the entire team to be confident that the app will work in any environment. I mean the environments are development environment, test environment, QA environment, production environment and so on.

What to do.

Make sure that all environments are the same.

Discuss around

Differences are likely to occur in the following cases. It is generally human error.

  • The time between code revision and release is long. Forgetting what modifications or environment changes have been made.
  • The release is done manually. Since manual work is always wrong in the first place, it becomes a difference.
  • It is difficult and tedious to prepare the same backing service as the production one. Then they substitute a similar but different one, which becomes a difference.

10 Administrative Processes

Background

What is Administrative Processes?

  • Database migrations
  • Interactive programming consoles (REPLs)
  • Running timed scripts, such as a nightly batch job or hourly import
  • Running a one-off job that executes custom code only once

In the original 12factor, it was a function of the application. The original 12factor says to do these processes as part of the app's functionality, but this should be stopped and some different approach should be considered. When the app scales horizontally, only one instance of the app will be able to run these functions.

What to do

Don't run the management process as a function of the application. Consider a different approach for one-time processes, timed batches, etc.

Discussion around

Instead of using cron for regular batches, it is better to prepare a RESTful endpoint and launch it from outside at regular intervals. Or, extract the batch-related code and make it a separate microservice.

11 Port Binding

What for.

  • When scaling horizontally, it is difficult to configure all network settings such as routing, scaling, high availability, fault tolerance, etc by hand. The cloud provider should do it.
  • When putting multiple apps on a single server, you don't want to manage the ports used by the apps in detail.

What to do

The app developer decides which port to provide externally for each app. The cloud provider connects that port to the actual published port.

12 Stateless Processes

What for.

We want to make it easy to start and stop the server so that we can quickly stop and scale the server at any time.

What to do

Have no data in the server that can be passed on between multiple requests. 6
Keep it in the backing service if needed.

13 Concurrency

What for.

When augmenting servers, we want to scale horizontally; we don't want to augment one machine, we want to scale by increasing the number of servers.

What to do

Design your application in a configuration where there are multiple processes to process. If the processes are separated into processes, it is easier to distribute the processes across multiple machines.

14 Telemetry

What for.

You want to effectively log your system. In cloud-native apps, you don't always have direct access to the actual server. If the server scales and the number of instances increases 100-fold, the amount of logs can also increase 100-fold.

What to do

Consider about how to measure the performance of the application.

Discussion around

Performance may include the following

  • Application performance monitoring (APM)
    • E.g., number of HTTP processes per second
  • Domain-specific telemetry
    • e.g., how many products were sold via iPad in the last 20 minutes
  • Health and system logs
    • e.g., system health check information. Event information such as start, stop, scale, etc.

Supplemental

There is no specific requirement to do this, but it seems to say that we need to be aware of how to capture and consider the content.

15 Authentication and Authorization

What to do

Implement security design/implementation from day one of development.

Supplement

Security is very important whether you are in a cloud environment or not. It should not be an afterthought.

Reference Links

Beyond the Twelve-Factor App
https://tanzu.vmware.com/content/ebooks/beyond-the-12-factor-app

The Twelve-Factor App
https://12factor.net/


  1. https://tanzu.vmware.com/content/ebooks/beyond-the-12-factor-app 

  2. How about playing around to find the mistakes? 

  3. https://12factor.net/ 

  4. "Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure." https://en.wikipedia.org/wiki/Conway%27s_law 

  5. This item is an extension of the contract-first development style. Roughly speaking, it means determining the specifications that the service will provide for the outside world. 

  6. If we say this in Java Servlet, don't have variables in session scope or application scope. 

Discussion (0)