Continuous integration (CI), continuous deployment (CD) and continuous delivery (CD)

Posted on April 30, 2021 by Adrian Wyssmann ‐ 5 min read

As a developer you are familiar with the terms continuous integration (CI) and continuous deployment (CD), which is often referred as CI/CD. However it's important to understand that these are different processes with different purposes.

The Development Process

Let’s have a look at the software development process. Regardless what methodology you use - Agile, Waterfall, … - the stages involved are the same:

  1. Requirements analysis
  2. Software design
  3. Implementation
  4. Testing
  5. Integration
  6. Deployment (or Installation)
  7. Maintenance

Ci and cd start playing an active role from step 3. to 6. Ultimately the source code is compiled and packaged into a deployable artifact - a .war file, a docker image, a windows installer - which is then deployed/installed into the target environment, or maybe first in a staging environment for further checks. Along the way, different activities like static code analysis, unit testing, integration testing, … will take place, to ensure good quality of your software. Sure a developer can ensure to perform all these activities but usually you don’t work alone and it shall be ensured that these activities are performed always and in the same way. That’s where teh concepts of ci and cd come in. If we draw the flow of activities in a line, we can easily show where the ci and cd play a role:

ci and cd flow

The “handoff” from one activity may impose some [Quality Gates], where certain attributes have to be fulfilled. For example you can define that commits only are allowed if they follow a specific format or the artifact is only created if all unit tests are passed.

Continuous integration (CI)

The CI process or practice ensures that the repetitive activities are done automatically and the developer does not have to take care of. Once a developer has implemented the code changes, ran it locally and finally debugged it, the code will be commit to the source control management system. From there the build server will take care of performing the necessary steps

  • compile code into an artifact
  • run unit tests and other automated tests (e.g. integration)
  • perform static code analysis
  • collect logs and test results
  • upload artifact to the artifact repository

Usually these activities happen several times a day, and if the developer has to perform this manually, it’s not only cumbersome but error-prone. The benefits of having the build server performs these activities are obvious

  • consistency in your development process and guarantees the same outcome regardless on who did the changes
  • early detection of regression issues due to constant testing of each changes
  • reduction of errors for otherwise manually performed steps
  • force best practices/disciplines like regular testing
  • constant and fast feedback on every committed change

Continuous Deployment (CD)

Once we have a released artifact - an artifact which contains all the code changes, is versioned accordingly and passed all [Quality Gates] - the cd process will take care of deploying the artifacts to the environment(s). It’s the same as for ci, a developer could to the same, but automating this process has the same benefit as for ci: Consistency in your deployment process and ensuring the same outcome without the danger of manual errors. Deployment ultimately also means the application is configured as needed so that it will run as expected in the target environment. This configuration may even look different e.g. assuming we have a software which connects to database - in a staging environment it would connect to a different db than in production.

As you can see in the image above, the deployment can happen to different environments and does not necessarily be fully autonomous and involve “manual” activities - often also imposed by regulatory requirements. For example

  • sing-off from product owners or release managers
  • coordination of deployments
  • perform manual tasks which cannot be automated (e.g. usability testing)

Continuous Delivery (CD)

Not every software can be continuously deployed - imagine a software which has to be installed on customer site, or deployed into an air-gapped environment. Also sometimes companies don’t want their software continuously deployed. So how continuous delivery differs from continuous deployment? Wikipedia says this:

Continuous delivery is the ability to deliver software that can be deployed at any time through manual releases; this is in contrast to continuous deployment which uses automated deployments. According to Martin Fowler, continuous deployment requires continuous delivery1

or if we look at the article from Martin Fowler1

Continuous Delivery is sometimes confused with Continuous Deployment. Continuous Deployment means that every change goes through the pipeline and automatically gets put into production, resulting in many production deployments every day. Continuous Delivery just means that you are able to do frequent deployments but may choose not to do it

So Continuous Delivery builds on Continuous Integration - automation is the key for continuous delivery - and is required if you want to do Continuous Deployment.

Here are some more articles to read:

Continuous integration and continuous delivery (CI/CD)

As mentioned above the term CI/CD is often used together, but strictly speaking they are different processes with different purpose, thus they may use distinct tools. In cloud-native environments it’s more common that CI and CD merges into a single process. However whether that makes sense depends heavily on your use-case. Whereas CI is a fully automated process, it does not need to be for CD. As soon as you have some manual interventions - e.g. sign-off - it’s important that your CD can deal with that. Also, every build goes trough CI, but not everything you build is necessarily deployed.

Deployment Strategies

When we talk about deployment, you have to know that there are different strategies:

  • Recreate: Version A is terminated then version B is rolled out.
  • Ramped (also known as rolling-update or incremental): Version B is slowly rolled out and replacing version A.
  • Blue/Green: Version B is released alongside version A, then the traffic is switched to version B.
  • Canary: Version B is released to a subset of users, then proceed to a full rollout.
  • A/B testing: Version B is released to a subset of users under specific condition.
  • Shadow: Version B receives real-world traffic alongside version A and doesn’t impact the response.

The NewStack: Six Strategies for Application Deployment explains it actually in a very nice and understandable way, how these strategies actually work. Another nice article is Kubermatic: Introduction to Deployment Strategies