What’s the difference between CI and CD?
Tags: devops, webdev, node
Published: 2020-12-04 11:48:23

Despite the common trend for automation of development processes, there are still some companies where testing and deployment aren’t automated at all. The lack of automated processes affects the speed of the change delivery and increases the influence of the human factor, which negatively impacts the entire company as a whole and not just the development department.

In this post I will try to explain the difference between the following processes: Continuous Integration (CI), Continuous Delivery (CD) and Continuous Deployment (CD). Most people don’t separate the last two terms, but we will discuss them separately to get a general understanding.

# CI, CD and one more CD: operation principle and differences #

## Continuous Integration (CI) ##

The Continuous Integration process automates the integration checks of developer changes merged into the rest of the code. 

This process might include static code analysis to detect vulnerabilities and inconsistencies with general development practices, application building and automated testing with dynamic vulnerability scanning.

Automating CI processes allows you to speed up development by eliminating routine manual checking of integration with the rest of the code and reducing the workload on the QA (Quality assurance) department due to faster identification of integration problems with the rest of the application. Also, a developer will not be able to save time by submitting changes for testing without any verification.

## Continuous Delivery (CD) ##

This stage is used to deliver the modified version of the application to production.

For example, the process of delivering Docker images is simply loading an image to the Docker image registry and then loading it from the host machine. In systems with increased security requirements, there might also be a situation where Docker hosts do not have access to any registries, and in this case, *docker save* and *docker load* commands can be used for delivery of Docker images.

In systems that don’t use Docker, delivery can be performed through SCM, apt/yum repositories, ssh, S3-compatible storage for VM images (built with Packer, for example) and many other methods, but their application field largely depends on emerging requirements and convenience of support.

In the example above with Docker, the changes will be delivered with the new image via loading to the Docker image registry.

Automation of CD processes allows you to speed up delivery, eliminate the influence of the human factor and also make delivery more accessible to the rest of the team.

## Continuous Deployment (CD) ##

The process is used to deploy a new version of an application to a production or testing environment. Usually, deployment is not isolated as a separate stage and is included in the delivery process. It depends on the specified requirements and the used tools, but the process implementation option is quite obvious, as a rule.

# CI/CD tools #

There are a lot of SaaS solutions available, and covering all of them would require another post. Let’s look at the main solutions that are easily integrated in most cases:

* GitLab CI is a great option for teams that use SaaS or on-premise GitLab instance. Uses YAML to describe CI/CD processes.
* GitHub Actions is a good, but a relatively new option for those using GitHub. Also uses YAML to describe CI/CD processes.

* Jenkins is a project with a long history, it allows you to use Groovy to describe CI/CD processes (which is an advantage and a disadvantage at the same time for many reasons) and your own DSL in Jenkinsfile.

# A detailed analysis of the processes on a fictional example #

Let's imagine a possible process in a fictional IT company and the possible requirements that are made by stakeholders. Take a small IT department with development, testing, and operations teams. The workflow is organized using Git-flow, and the deployment is done on Docker hosts. Let's describe the main requirements of the parties in the table.

![The table](https://github.com/hostman-articles/dev-to/blob/main/table.png?raw=true)

After collecting the requirements, we can outline how the CI/CD processes will be performed in the team:

![The flowchart](https://github.com/hostman-articles/dev-to/blob/main/flowchart.png?raw=true)

# CI Phase. Analysis #

The integration process does not have to be general in all cases. It is much more convenient to describe different scenarios for each situation. Let's describe possible situations as an example:

* **When updating a Pull/Merge Request**, a static code checking is performed for compliance with the company's coding standards, a static code analysis for possible errors and vulnerabilities, an automated unit and functional testing using stubs instead of external services. 

If necessary, the image will be built for further integration with the rest of the company's services and external ones.

* **If we have changes in the main branch** the process is similar to the above example. But there is an exception that now the image for integration is always built: for further deployment at the stand for general E2E and acceptance testing with the rest of the components.

* **When installing the tag**, the image with the application is built for production and post-deployment smoke testing.

Why can't we build the general CI process? 

To tell you the truth, it does not make any sense. If you build an image for integration testing after manual confirmation for the release branch, then we will, without a doubt, forget to start the build manually, and the QA department will check the out-of-date version of the application. It is a waste of time to conduct compliance with the coding standards and unit / functional testing on a tag version, as all the changes are already in the release branch.

The more automated tasks there are, the more worthless work will be done in the general process.

# CD (Delivery) Phase. Analysis #

In our case, the delivery is loading a Docker image with an application into the Registry. From the Registry the images will be loaded onto a specific Docker host during the deployment process. The Registry can be shared or separate: for the development and test environment and the production environment. It depends on the security requirements in a company.

# CD (Deployment) Phase. Analysis #

In our case, a deployment can be performed to the production environment by redirecting all the new HTTP requests to a new instance of the application (the maximum request time is limited within reason above for ensuring the deployment without downtime).

It is worth drawing attention to cloud hosting if you manage a small project and don’t need to create your own infrastructure. It allows you to automate project development by setting up CI/CD process.

For example, [the Hostman platform](https://bit.ly/3mhvSyv) will be responsible for delivering changes. A Docker image will be built in the selected branch from the new version of the code and will be automatically deployed without downtime. In our example, automation would have ended at the stage of merging the developer's changes into the release branch.

# Conclusion #

I hope this post helps you to clarify and understand the differences between CI and CD, as well as to see how important it is to automate these processes.

To sum it up, a CI/CD pipeline implementation is an ongoing process. It is constantly changing according to the new requirements and needs of a company. It is obvious that the CI/CD process requires additional tools and extra time. However, we can reduce costs and time by using ready solutions and services.

The decision is yours! I believe these processes automation should be integrated in every company that specializes in development of applications, products, platforms etc.