Smith Optimal Solutions LLC

Microservice Development

Development of microservices following the 12 Factor Principles and industry best practices.

The 12 Factor Principles

  1. Codebase - One codebase tracked in revision control, many deploys
  2. Dependencies - Explicitly declare and isolate dependencies
  3. Config - Store config in the environment
  4. Backing services - Treat backing services as attached resources
  5. Build, release, run - Strictly separate build and run stages
  6. Processes - Execute the app as one or more stateless processes
  7. Port binding - Export services via port binding
  8. Concurrency - Scale out via the process model
  9. Disposability - Maximize robustness with fast startup and graceful shutdown
  10. Dev/prod parity - Keep development, staging, and production as similar as possible
  11. Logs - Treat logs as event streams
  12. Admin processes - Run admin/management tasks as one-off processes


Beyond the 12 Factor Principles

Kevin Hoffman expands the original 12 Factor Principles for the modern Cloud Platform world.

  1. One Codebase, One Application - Cloud-native applications must always consist of a single codebase that is tracked in a version control system. A codebase is a source code repository or a set of repositories that share a common root.
  2. API First - An API is to be consumed by client applications and services.
  3. Dependency Management - A cloud-native application never relies on implicit existence of system-wide packages. For Java, this means that your applications cannot assume that a container will be managing the classpath on the server.
  4. Design, Build, Release, Run - In addition to the twelve-factor build, release, run trio, the discrete design step is crucial.
  5. Configuration, Credentials, and Code - Factor 3 of the original 12 factors only states that you should store configuration in the environment. I believe the configuration guidance should be more explicit. Treat configuration, credentials, and code as volatile substances that explode when combined.
  6. Logs - Logs should be treated as event streams, that is, logs are a sequence of events emitted from an application in time-ordered sequence. The key point about dealing with logs in a cloud-native fashion is, as the original 12 factors indicate, a truly cloud-native application never concerns itself with routing or storage of its output stream.
  7. Disposability - On a cloud instance, an application’s life is as ephemeral as the infrastructure that supports it. A cloud-native application’s processes are disposable, which means they can be started or stopped rapidly. An application cannot scale, deploy, release, or recover rapidly if it cannot start rapidly and shut down gracefully.
  8. Backing services - A backing service is any service on which your application relies for its functionality. A bound resource is really just a means of connecting your application to a backing service. When building applications designed to run in a cloud environment where the filesystem must be considered ephemeral, you also need to treat file storage or disk as a backing service.
  9. Environment Parity - The purpose of applying rigor and discipline to environment parity is to give your team and your entire organization the confidence that the application will work everywhere.
  10. Administrative Processes - I contend that, in certain situations, the use of administrative processes is actually a bad idea, and you should always be asking yourself whether an administrative process is what you want, or whether a different design or architecture would suit your needs better.
  11. Port binding - Your cloud provider should be managing the port assignment for you because it is likely also managing routing, scaling, high availability, and fault tolerance, all of which require the cloud provider to manage certain aspects of the network, including routing host names to ports and mapping external port numbers to containerinternal ports.
  12. Stateless Processes - Applications should execute as a single, stateless process. As mentioned earlier in the book, I have a strong opinion about the use of administrative and secondary processes, and modern cloud-native applications should each consist of a single,1 stateless process.
  13. Concurrency - A much more modern approach, one ideal for the kind of elastic scalability that the cloud supports, is to scale out, or horizontally. Rather than making a single big process even larger, you create multiple processes, and then distribute the load of your application among those processes.
  14. Telemetry - Auditing and monitoring cloud applications are often overlooked but are perhaps some of the most important things to plan and do properly for production deployments. If you wouldn’t blindly launch a satellite into orbit with no way to monitor it, you shouldn’t do the same to your cloud application.
  15. Authentication and Authorization - Security is a vital part of any application and cloud environment. Security should never be an afterthought.

Reference: Beyond the Twelve-Factor App, Kevin Hoffman, O'Reilly Books