Verification
To ease the verification of the implementation, this section includes a checklist that can be used to ensure that the application covers the different principles adequately.
I. III. V.
Codebase: One codebase tracked in revision control, many deploys
Build for each application is independent
Shared libraries have their release process
Strong code management flow in place
Automated tests with reasonable coverage
Dependencies: Explicitly declare and isolate dependencies
II. IV.
Libraries dependencies declared via dependency manager apps
Dependencies with limited system-wide dependencies
Limited System-wide dependencies are handled via the dependency manager or IaC
Dockerfile with all dependencies well-declared
Dependencies with the supported version number declared
External dependencies explicitly stated in the configuration
Config: Store config in the environment
DB connection URL/credentials are not in the code
External services URL/credentials are not in the code
All Configuration variables using Environment variables or external configuration servers
If a configuration file exists in code, it should not be included in the source control, and it’s always generated in the CI/CD pipeline using secured variables
Backing Services: Treat backing services as attached resources
Persistent storage managed outside of the application servers
DB used as an external service
External services configuration is easily adjustable
Configurable timeouts for connections to attached resources
Build, Release, Run: Strictly separate build and run stages.
There is an explicit separation between the different phases of a release
Each release has its ID, and there is a good registry that keeps track of them
Each release is immutable
Robust CI/CD pipeline in place
Separate release process to deploy artifacts to different environments
Processes: Execute the app as one or more stateless processes
No sticky sessions are required for the application to work properly
External services manage cache & storage
Processes are easily replaceable
The health check is in place for processes/applications
Port binding: Export services via port binding
Each application with a predefined bind port and bind-address
Standard ports used for its specific traffic
Dockerfiles with the PORT definition
Only non-privileged ports are used
Concurrency: Scale out via the process model
VIII.
VII. IX. XI.
VI. X. XII.
The application can scale horizontally
The application can handle failures and errors gracefully
Robust monitoring and logging in place
Disposability: Maximize robustness with fast startup and graceful shutdown
Stateless application
No execution dependencies between processes
The application facilitates upscaling, downscaling, recovery from failure, start, and stop execution.
Dev/Prod parity: Keep development, staging, and production as similar as possible
IaC applied whenever possible
Continuous deployment in place
Same backing services between the environments (including the identical versions)
The same external libraries are used in all environments
Monitoring & logging tools with the same capabilities in different environments
Hostnames not used for the conditional routing logic
Logs: Treat logs as event streams
Logs use a structured format
All relevant events are logged
Logs are centralized in a searchable location
Admin processes: Run admin/management tasks as oneoff processes
Administrative tasks are executed as separate processes
Administrative tasks are tracked in a different codebase
Administrative tasks are as automated as possible
Administrative tasks with limited access to the environment and backing services