The DevOps novel The Phoenix Project dramatically illustrates the need to create frequent, small code changes that are quickly deployed. In the book, the operations team is constantly being handed random, large, or quickly made code changes that need to be deployed. Most of the book revolves around operations cleaning up messes and trying to figure out a process to keep things running smoothly.
The main character soon discovers that a better way to handle releases is by making small, frequent changes and automating the deployments. These same concepts are also included in the operational excellence pillar in the white paper AWS Well-Architected Framework.
Continuous integration and continuous deployment, or CI/CD, is the formal process that enables these frequent, automated deployments. In this article, you’ll get an introduction to what continuous integration and continuous deployment are, how they’re different, and how they work together.
What is continuous integration?
Continuous integration is an automated way to combine versions of code and validate the result. For example, if your team merges their changes into the main branch every day, you could set up a pipeline that automatically builds and tests the changes before they’re merged. That would be an example of continually integrating your code—or continuous integration.
The goal of continuous integration is to get your code into the main branch as quickly as possible. To support this, you will need to make small, frequent commits to the main branch. The idea here is that it’s a lot easier to figure out what could be broken when doing a small change versus a big one. Also, you usually set up automated tests so that if something does break in a commit, it can be automatically rolled back or the pipeline could just prevent it from getting merged in the first place.
The best way to get started with continuous integration—and your full pipeline, for that matter—is to start creating unit tests as you add features to your product. Another easy win is to add linting tests. Once these tests are in place, set up a pipeline and start running them on every commit. If your repository supports it, show the results of these tests in merge requests.
What is continuous deployment?
Once the code for your new feature has been integrated into your main branch and it’s been validated through testing, what happens next? Ideally, it should get to your customers as fast as possible so they can enjoy the new feature that you spent so much time on.
Continuous deployment is the process of automatically pushing out your new features to customers without any manual steps in the process. As long as all your automated tests pass, then the build is pushed out to customers. This whole process should be triggered for every commit merged into your project’s main branch.
There is another CD you need to look out for that’s almost the same as continuous deployment—it’s continuous *delivery*. Continuous delivery is almost the same as continuous deployment, except the former adds a manual approval step. Instead of automatically pushing to prod, continuous delivery waits for someone to push a button.
Getting started with continuous deployment can take a bit more time than continuous integration. It can be a bit more daunting, too. If your application is still in the testing phase, then you should add continuous deployments right away. You have nothing to lose.
If you have a well-established application that you’re manually running deployments on, first write a script to run the deployment. Start using the script to run deployments, making changes as needed, until you’re satisfied that it works just as well as the manual process.
Once the script is created, you can set up continuous delivery in your pipeline. Essentially, you’re just adding a manual step that executes your deployment script. Start adding some tests to automatically roll back deployments if they start breaking things. Finally, once you’ve run the deployment from your pipeline without errors a few times, change the manual deployment step to automatic.
How to release features on a specific date
If you’re sending all your commits to prod as soon as they come in, how do you make sure a feature isn’t released until it’s ready? That’s where *feature flags* come in.
When you start working on a new feature, create a flag and wrap all your new code for the feature in *if* statements. As long as the feature flag is disabled, your users will see the old feature and run the same code. Once the release date for your new feature rolls around, just flip the switch and everyone can instantly enjoy the new feature.
An advantage of using feature flags over keeping the code in a separate branch is that you can conditionally enable the flag based on a user ID. That means you can serve the new feature to your QA team in prod.
How are they different?
While both continuous integration and continuous deployment are automated steps of getting the software to your end users, they each take care of a unique part of the process. Continuous deployment only cares about getting your changes out to end users as fast as possible. Continuous integration, on the other hand, isn’t especially concerned with the end user. It’s more about helping the developer keep code functional and formatted well, and prevent old bugs from creeping back in.
How do they work together?
Continuous integration is a requirement for creating a reliable continuous deployment solution. If you’re going to be deploying every commit in your main branch to production, you need to make sure it works. That’s where continuous integration comes in.
If you’re working on an application that requires a specific release cycle (once a month, for example), you may not want to use continuous deployment. You could instead use continuous delivery and continuous integration: continuous integration to help keep your main branch in a good state and continuous delivery so you would just need to push a button to deploy to prod when you’re ready to release.
You may also want to wait on implementing a continuous deployment solution if you’re just starting to add a delivery pipeline to your project. Work on continuous integration first, practicing the art of making small, frequent commits and adding tests around your code to make sure it works. Once you’re comfortable that the CI testing is keeping bad code out, then it’s a good time to start automating your deployments.
You’ve read the difference between continuous integration and continuous deployment. You’ve also learned how they work together. You should now have a basic understanding of when to use each and some ideas of how to get started.
If you need a solution to deploy an API gateway from your CI/CD pipeline, Tyk provides a full-featured solution that includes an open-source option.