12 factor principles to design a cloud native application

Lalitha V
5 min readApr 25, 2021

--

One code base, one application

Have single code base to deploy that is loosely coupled, highly cohesive codebase. Single code to deploy across environment. For a developer, this makes it easier to create CI/CD pipelines.

Dependency management

Application’s dependencies should be clearly defined and not rely on a system-wide packaging/location.

Use buildpack, Set up dependency frameworks and runtime support, needed to build and/or run an application, on a Cloud platform such as Cloud Foundry.

Design, build, release and run

The concept that each phase should be executed as isolated independent steps.

The design phase declares the dependencies. The build phase pulls together the dependencies to produce a build artifact with a build number. The release phase combines the build artifact with application or environment specific configurations, and tags the output with some versioning for tracking/audit purposes and finally, the run phase defines the process of launching and running the application. The run phase is usually the responsibility of a Cloud platform

Configuration, credentials, and code

Externalise as environment variables. This enables an application to be configurable without the need to modify a release.

Log

Logs dictate that logging output should be treated as event streams and should be simply emitted out via standard out and standard error. The benefits of this principle are three-fold.

  1. All management and processing of logs are handled externally by the Cloud platform and external tools.
  2. The second is the support for horizontal scaling. Should an application be scaled horizontally and that the logging was managed by the application, developers would need to introduce logic to handle the identification of which application instance a log comes from.
  3. By deferring the logging stream externally to the cloud platform, storage, processing, and viewing of logs can be done independently from the application itself.

Disposability

Disposability is a requirement due to the ephemeral nature of Cloud applications. Simply put, an application should be shut down and started up quickly so that it can be ready to handle incoming traffic.

Backing services

Backing services is part of the original 12 principles. All backing services should be treated as bound/attached resources. A backing service is simply any service that is consumed by an application. A bound/attached resource is simply the connection between an application and a backing service.

Environment Parity

the goal was to ensure that gaps between development and production were small or non-existent.

Administrative task

Depending on the Cloud platform, one should evaluate and consider the best course for performing the administrative tasks. For example, on Cloud Foundry, it would not be practicable to run the administrative task as a separate spawned process with an instance of an application in the same container. The application itself may be scaled up to multiple instances, or there is no guarantee how an application would behave/live for the duration of the administrative process. The former scenario may introduce complexities to the handling of the administrative task relative to each instance.

Port Binding

The contract with the execution environment is binding to a port to serve requests. The port-binding approach means that one app can become the backing service for another app, by providing the URL to the backing app as a resource handle in the config for the consuming app.

Stateless processes

An application’s processes should be stateless and share nothing. Stateless processes here means that a single process should not expect to retain any state information, whether it is on a container’s disk or its memory, since there is no guarantee that information will be retained. Should state need to be retained, it should be done so externally to the application through backing services, such as Redis.

Share nothing processes relate to when more than one process runs concurrently in the container. A good practice would be to avoid sharing and storing state between these processes; this makes the application less complex and easier to maintain. Again, utilize an external backing service to store state information, should this be required.

Provide scalability and durable in handling data integrity in the presence of ephemeral containers.

share nothing, stateless and disposable, which make them prime candidates for efficient horizontal scaling.

Concurrency

The alternative to horizontal scaling is vertical scaling, whereby an application’s underlying server/system is scaled by increasing its CPU or RAM. In general, the stateless processes follow a Unix process model that enable developers to architect their application in such a way that enables them to divide the workloads as separate independent programs and scale them accordingly (https://en.wikibooks.org/wiki/A_Quick_Introduction_to_Unix/Files_and_Processes). In more current architectural models, Microservices have a division work that is well defined and each Microservice in itself is a single application that can be individually and horizontally scaled. For the developer following this principle, it will lead to having code that is less complex and easier to maintain without the need to have cached information between itself and its dependent or calling services.

Telemetry

For cloud management, telemetry is critically important: to the human eye, IT infrastructure looks very similar whether the hardware is performing optimally or not. Telemetry gives IT professionals the ability to observe components and monitor applications in a deeper way, with metrics that track performance, utilization, energy consumption, and more.

Grace application fault tolerance

The purpose of fault tolerance is to increase the reliability and availability of a system, allowing it to respond gracefully to an unexpected fault. Apply back pressure.

Authentication and authorization

Most organizations have multiple classes of users with different identity needs: their workforce, their business partners, and their customers. Even if you’re using the same IAM platform for all three, you’ll need to take a different approach for each.

https://auth0.com/blog/what-is-iam/

API first

Define a contract on what and how other applications would interact with your application.

Responsibilities are well understood. what would it expose and exposed to.

Systematic versioning

A popular approach to versioning has been the semantic versioning approach, which follows the major.minor.patch release number.

Your application doesn’t have to be cloud-native in order to be deployed and running on Cloud Foundry.

When migrate a non-cloud application, it helps to focus first on few principles to get started with cloud journey i.e. Cloud Ready, then focus and remaining to move to make app Cloud Friendly and then Cloud Native Application.

Reference: Cloud foundry for developers from Oreilly publications.

--

--