Article

Low-risk releases: Creating value through continuous delivery

December 09, 2019

A good development process allows your developers to offload repeatable tasks and focus on more important things, like feature development and bug fixes. And to implement a successful process, you need to think beyond "automate everything!" and look at your entire software life cycle. As you do this, remember: the focus should be equal parts “continuous” and “delivery,” especially the things you do to continuously deliver value to your customers. 

At the end of the day, continuous integration and continuous delivery (CI/CD) is all about delivering more value to customers—faster. But, the secondary benefits of a well-designed continuous delivery system are just as appealing, including reduced software risk, fewer broken releases and less stress. (The fact that it happens to make life easier for the engineers doing manual deploys is a nice bonus too.) If you’re ready to capitalize on this, here’s what you need to do.

Implement continuous delivery

Before you can implement a CI/CD process, you need to examine and establish your value stream—all the steps it takes to deliver value to your customer, starting with the idea. Once you understand your value stream, you’ll be ready to dive into the three steps that will help you implement a CI/CD process aligned to your overarching goal:

Step 1: Configuration

Servers should be created for a predetermined purpose, then destroyed. Create a configuration for each server as a template, and store that template just as you would store code. This enables you to create servers at will for a particular task, with consistency you can rely on.

For instance, if you have a web application that requires a particular configuration, you should be able to pull that configuration from source control and create a server that mirrors that same application server in testing, staging and production. Once you’re done with that server, you can discard it.

 

How to get started with configuration management

Document the plan for creating configurations of known servers in the production environment. Then, create a template that recreates the configuration of each server. Since this can be difficult and time consuming, here are some methodical steps:

  • Create a server with a suitable hardware profile

  • Create a script to "provision" and set it up

  • Push the software to the server

  • Ensure every change you make to get it running is reflected in your setup script

  • Test the script to make sure it's repeatable and predictable

You'll need virtualization for this; you won’t want to provision a physical server each time. That would take a lot of effort and get expensive fast. Instead, create a "server" in a hosted VM environment.

Step 2: Optimization

Most slow build systems have similarities, including common roadblocks that are preventable with a change in process. Here are ones to watch for:

  • Long-lived branches: When developers create a branch and stay in it for long periods of time without committing, it creates merge problems. Their code is changing while the rest of the code in the system is changing in parallel. Merging them together becomes time consuming and uncovers regressions. 

  • Manual processes: Manual processes create a bottleneck when a human is required to move code forward in a process. The flow of the system becomes dependent on that person to move the code forward, otherwise the flow stops. 

  • “Works on my machine:” When developers build software on their local machine for long periods of time without deploying/testing, problems arise. You’ll face merge conflicts and dependency issues that take time to solve and slow the overall flow. 

 

How to start optimizing the build process

The most important thing to do is focus on removing bottlenecks and preventing work in progress from entering your development workflow. You can do that by:

  • Moving to a “trunk-based” development model: This model, also called “mainline development,” is where developers collaborate on a single branch (usually called "master" in git) and build the software from that branch. In this model, every developer commits at least daily.
  • Automating tests: This effort is a big lift, as it requires significant time and problem solving, but getting everything automated ensures that software can move freely throughout your value stream.
  • Automating builds: Every commit from a developer should trigger an automatic build. This completely removes that step from the developer’s workload, freeing them to focus on the software itself rather than its implementation.

Step 3: Automation

Automation of manual processes reduces friction and improves your overall flow. It also improves quality as you reduce the possibility of human error. 

 

How to get started with automated deploys

Examine the flow outside of the deployment process to make sure artifacts are moving in and out of the deployment process uninhibited. Any improvements to the deploy process itself will be ineffective if your inputs aren’t coming in quickly or if your outputs are stalled upon deployment. 

Deployment is the “bridge” between developers and operations, so it relies on several moving parts to be successful:

  • Consistent configurations: See step one. If your configurations are different, your deployment will fail immediately.

  • Good automated testing: This will ensure that changes aren’t held up in testing before they’re deployed.

  • Automated steps: This goes for each step within the deployment process. A single push of a button should move software from one stage to the next. 

Once you’re happy with the input and output flow, focus on the parts of the process that require manual work, and prioritize them according to which ones can be automated with the lowest effort. It may be tempting to prioritize the biggest process but by improving on the smaller ones first, you get faster flow immediately. What you learn from solving the smaller problems can then be applied when you tackle the larger automation efforts.

Implementing a CI/CD practice in your organization is a major undertaking. It can be difficult to start. You’ll have to make lots of changes and you’ll likely be met with a lot of resistance. But it’s a change you need to make to continually deliver value to your customers. You can optimize your systems, configurations and frameworks to death and get nowhere, so get clear on the real goal. Optimize to make the human experience of your product better. When you step back and view your entire system from that lens and locate and resolve bottlenecks, you’ll see faster flow.

As you improve your systems through configuration, optimization and automation, you’ll also see its effect on your team. Developers will be able to focus on feature enhancement and bug fixes. Operations will be less concerned about deploying new software and less reserved about changing their infrastructure. When your process provides predictability and faster flow, you have happier engineers—ones delivering more customer value than ever before.