Five-Star Applications

Have you inherited a mess of an application that isn’t ready for a modern cloud deployment with an orchestration layer such as Kubernetes? Evolving such an application can be daunting, but your team should be able to tackle it with a simple five-step process.

Like the 5-star deployment scheme for open data,1Tim Berners-Lee. “Linked Data – Design Issues” <https://www.w3.org/DesignIssues/LinkedData.html>. Retrieved 1 Apr 2024. See also <https://5stardata.info/en/> we can build out a sequenced approach for applications. Each step builds on the previous one and offers value without requiring teams to immediately progress to the next step. Each step addresses different aspects of the twelve-factor application to allow progressive adoption of the twelve-factor application approach.

The twelve factors are:2The definitions of the twelve factors are copied from Wikipedia. <https://en.wikipedia.org/wiki/Twelve-Factor_App_methodology>. Accessed 1 Apr 2024.

  1. Codebase:There should be exactly one codebase for a deployed service, which should be used for many deployments.
  2. Dependencies:All dependencies should be declared without implicit reliance on system tools or libraries.
  3. Config:Configuration that varies between deployments should be stored in the environment.
  4. Backing services: All backing services are treated as attached resources and attached and detached by the execution environment.
  5. Build, release, run:The delivery pipeline should strictly consist of build, release, and run.
  6. Processes:Applications should be deployed as one or more stateless processes with persisted data stored on a backing service.
  7. Port binding: Self-contained services should be available to other services by specified ports.
  8. Concurrency: Concurrency is advocated by scaling individual processes.
  9. Disposability: Fast startup and shutdown are advocated for a more robust and resilient system.
  10. Dev/Prod parity: All environments should be as similar as possible.
  11. Logs:Applications should produce logs as event streams and leave the execution environment to aggregate.
  12. Admin processes:Any needed admin tasks should be kept in source control and packaged with the application.

Security and monitoring are outside the scope of the 5-star application because they are properties of the orchestration layer (e.g., the Kubernetes cluster). However, development teams should build the application with security in mind from day one, and the orchestration layer should run the application as soon as possible.

1 Star: Source Code Repository

12 Factors: Codebase, Admin processes.

The first step is to ensure all of an application’s code is in a single repository. Libraries that can be bundled and referenced as any other dependencies can be in their own repositories, especially if multiple applications use them. Having one repository per artifact and only one artifact per repository can make CI/CD automation easier.

All administrative processes should be scripted and included in the application source code repository. Administrative tasks should be part of the application rather than separate scripts when possible. If administrative scripts are updated when the application changes, anyone can get the correct script by referencing the version corresponding to their running application.

The application should have unit tests that build confidence that it works as intended. These tests should be in the same source code repository as the application to ensure that the version of the tests matches the version of the application they are testing.

Finally, a single document should describe the steps for installing dependencies and running the application. This document should be kept in the same source code repository as the application it describes.

Some teams use “monorepos,” but this requires rigor that is easier to manage by using separate repositories for different applications. Generally, having each application in its repository allows vendors or teams to be changed as needed on a per-application basis without worrying about conflicts from multiple vendors or teams working in the same code repository. If you are considering a monorepo, wait until the team has developed the rigor that multiple repositories enforce.

2 Stars: Dockerfile

12 Factors: Dependencies, Build, Processes, Port binding, Disposability, Backing services, Concurrency, Logs.

After the team has consolidated the application in a single code repository and documented how to run it, they are in an excellent position to create a Dockerfile describing how to create a Docker image for the application.

Using an image to run the application allows each team to move at its own pace, which is one of the fundamental aspects of agile project management.

The application should have a Dockerfile in its code repository that lets a developer build a Docker image to run the application. The instructions should be updated to reflect the application using the Docker image.

A dockercompose configuration file should be in the code repository to start any services the application needs. These services should run in separate containers from the application container. An alternative method is to create Kubernetes configuration files that let the developer run all of the service and application containers in Minikube. Using Minikube rather than Docker Compose gives the team a head start on the fifth star.

The application should not store any information that a future request to the application might need. Doing so breaks concurrency. Some applications use techniques like sticky sessions, but modern web stacks are strong enough to handle almost all workloads.

The application should not use the container’s filesystem for data storage. Instead, it should use other services for persistent data storage, and these services should be configured in dockercompose or similar configuration files. For example, PostgreSQL might need to run in a container for relational data and MinIO in another container to mimic AWS S3 blob storage.

The application should send any log messages to its standard output or standard error file handles rather than writing to log files. This gives good feedback during development and supports log aggregation when deployed in cloud orchestration environments.

Ideally, a single script should let a developer build the image and run the application in a local containerized environment. This removes ambiguity about what the developer should do and ensures everyone runs it the same way across all developer environments. It also ensures the team knows any processes that might be done manually. It’s easy to forget about manual steps.

3 Stars: Configuration

12 Factors: Config, Dev/prod parity.

Using environment variables to configure the application is a natural next step. When using Docker Compose and Kubernetes, docker containers use such variables to pass configuration information into the containerized environment.

The same code can run in different environments by isolating the changes between environments to settings in environment variables. This reduces the risk of bugs entering production: different behaviors are due to different environment variable settings.

N.B.: Run-time environment configuration concerns the application’s technology infrastructure context, not application behavior. Feature flags and other behavior settings should be managed through other processes. Most languages have feature flag libraries that allow the run-time setting of flags.

4 Stars: CI/CD

12 Factors: Dev/prod parity, Release.

Once the configuration differences are isolated to environment variables that can be supplied when the container starts up, the CI/CD pipeline can build the image, test it, and then promote it for use in production without having to build a different image for production.

5 Stars: Helm Chart

12 Factors: Dev/prod parity, Run.

The final step is creating a Helm chart that provides all Kubernetes configurations necessary to run the application, with configuration values supplied through the Helm values file. This provides a well-defined and well-documented boundary between the application development team’s and the infrastructure management team’s responsibilities when deploying the application to shared infrastructure.

For example, the application team might decide that the application needs a PostgreSQL database connection. The infrastructure team can create the database and add the configuration information to the Helm chart configuration for the application.

Conclusion

You don’t have to jump from an unorganized mass of code to building Helm charts for your microservices and applications immediately. You can work through each star, ensuring the application still works, and the team is comfortable with the changes before proceeding to the next star.

Are you wondering what a 5-star application might look like for you? Schedule a free consultation, and let’s see what’s possible.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top