Click to learn more about Dave Karow.
There are a variety of ways that teams implement continuous delivery. However, when you start to analyze them, you begin to see some themes emerge. While there is definitely more than one way to succeed with continuous delivery, there are four principles that seem to appear in every team’s process.
Reducing Batch Size
Every continuous delivery team places a high importance on reducing batch size. This means reducing the number of changes involved in a production deployment. In fact, it has been reported that some teams wouldn’t be able to sustain their release process if the batch size increased greatly. Therefore, many teams aim to achieve a single-piece flow — this is when parts are moved through production with no work-in-process in between, either one piece at a time or a small batch at a time.
Reducing batch size also means a reduction in the amount of time a change takes to go from an engineer’s keyboard to the user, and there has proven to be a direct correlation between delivery performance (affected by the batch size) and overall organizational performance.
Trunk-based development (TBD) is a source-control model where developers commit their code to a single branch, instead of multiple long-lived feature branches. The two main forms of TBD are committing directly to master and using only short-lived feature branches (reviewed and committed back to master no less often than daily). Both forms of TBD allow more time to be spent on building with less time consumed with the resolution of code conflicts (AKA “merge-hell”). The journey towards the single-piece flow we spoke of above is nearly impossible without practicing trunk-based development.
Architecture Adapted to Make Pushing Changes Easier
Some teams are still working on large monolithic systems, while other teams have moved to an ecosystem of many small services (microservices). Both architectural approaches have implications for how you achieve continuous delivery. A microservice architecture means that there are multiple small, independently deployable artifacts that are being managed by multiple teams, whereas a monolithic architecture implies multiple teams working in the same deployable system.
The main question to answer in either case is, “How can we make it easier for engineers to understand the impact of the changes they are pushing out?” Clearly, it’s easier to comprehend when all the changes are being made by a single team. When it is a case of multiple teams landing changes in the codebase at the same time, it can make the process a lot harder. Tooling and process help at any scale, but when architecture leads to an even modest number of developers making changes to more than one aspect of your system, they become essential.
Whether monolith or microservice or somewhere in-between, setting yourself up to work with smaller batch sizes and faster deployment tempos will always make the process of understanding the changes easier.
Teams that achieve continuous delivery all have at least one thing in common: They have created or assembled a custom delivery platform specific to their needs. No two environments are the same, but the need to reduce manual work and increase automated rigor applies to us all. Tooling should allow your team to focus on flow, forward momentum, and built-in safety. Here are some examples of tooling teams have built. The idea is to have important and frequently needed things happen reliably with just a few keystrokes, whether it be at a command line, to a chat-bot, or in some web UI. None of these should be a ticket for another team to fulfill from a queue:
- Deploying a specific version of a service into an environment
- Requesting a hold on production deployments
- Signing off on a version as being ready for production
- Tracking which version of each service is deployed into an environment
- Showing a history of previous deployments
- Reporting which new versions of a service are available for deployment
- Performing Data Management tasks in an environment (such as reseeding test data or importing scrubbed production data)
- Reporting overall service health in an environment
- Providing a service registry — a way to view metadata about the service in an environment, such as team ownership, service dependencies, and quick links to production dashboards