CI/CD, what is this?
Recently I have been exploring the DevOps world. In my path I encountered the Continuous Integration and Continuous Deployment. In order to understand what they mean, I attended a course on Udemy by Ali Rizavi and read some articles around. You can find the references on bottom of this article. I wrote this article as a summary for me, but I think it can be useful even for others.
Continuous Integration is a practice that aims to integrate new code changes and keep the source code base in a good state. A way to achieve it can be integrating new changes and automatically testing the overall code.
On the other hand, Continuous Delivery aims to regularly create releases ready to be deployed, not necessarily in production. The release can be used in beta stages or in production environment. The release has to be consistent and bug free.
Continuous Deployment is the practice to release frequently in production (to the end user). The release is created by the Continuous Delivery process.
Normally when you talk about CI/CD you could hear about DevOps. The figure of DevOps can be viewed as the fusion between System Administrator and Developers where the responsibility is shared. DevOps doesn’t use CI/CD only, but that is an important aspect.
What are the motivations of CI/CD?
- Moving fast, time to market: building a good release in few time is a key point for reducing the time to market;
- Increase reliability: automating tests and having pre-stage environments allows you to reduce the bugs;
- Rapid troubleshooting: creating frequent release means little differences between them, so it reduces the field of troubleshooting;
- Avoid stress of releasing: a CD allows you to have little, but frequent deployments, so you are less scared about them.
The CI/CD practice is often translated in pipelines. The pipelines are a series of subsequent actions/stages that normally starts from the source code changes and stops the sequence if there is an error in a task.
What are the components of the CI/CD pipelines?
- Source code repository triggers: normally when merging a new feature;
- Builds/actions: the compiling of the code or other disparate actions as email sending or script execution;
- Tests: verifying if the new release works as expected, they can be automatic or manual;
- Approvals, manual or timely: some kind of approval to go forward with the process;
- Deploys: the act of installing the release in a live environment.
An example of pipeline
In figure 2, there is an example of CI/CD pipeline. Here is explained step by step.
After a push of fresh code in repository, it is build to create the unit of release. The building phase is the first test, in fact, it checks for compiling errors.
The unit of release is tested by integration tests. The tests have to be prepared by the developing team or Quality Assurance team. They are created to assure that every past feature is not afflicted by new changes and the new changes behavior as expected. Passing the tests, the release is deployed in a beta stage to be inspected by humans or other testing tools.
After the deploy on beta stage, an email is sent to the Service Owner (or Quality Assurance team) to give the approval to go in production.
The deploy in production is composed by 2 steps: a DB change and the installation in the live production environment.
The DB change is not always mandatory, it depends on the code changes. In order to be complete, I showed this action as separated from “Deploy on production”.
How to design the CI/CD pipeline?
In order to design a pipeline, you should understand what are the involved components of the service that you are releasing.
Normally the release is composed by:
- binary code
- database structure or data
- static assets
Every these mentioned component leads to a change in the infrastructure that you use to provide the service.
The steps to design the pipeline are:
- Identify the common changes, find the changes that can afflict the service;
- Identify the updated components, you have to iterate for each change and address what is the impact of the changes on the components;
- Identify the action to perform the deploy/update,
- Model the process, you have to model the process considering the business needs.
In the CI/CD pipeline there are some common issues. I list some of them.
Database migration, the structure of the data can change during the evolution of the application. The action to change the structure is called database migration. In order to make the release repeatable and consistent, your release should include scripts to manipulate the database. There are a lot of library that create Data Definition Language/Data Manipulation Language files that allows to go forward and backward with your database accordingly with source code version.
Monitoring the application, to trigger a “back out” after a broken release or to verify that a new change doesn’t break the software. If we are talking about a web application, the usual checks are the HTTP ping, verify a 200 OK of a test page; and the deep HTTP ping where you check the content inside a page.
Other tests can be functional checks, where you interrogate your application and verify the response. It can be done simulating actions on User Interface or simply doing some REST call.
In addition, other common tests can be related to the system metrics, as CPU, RAM and swap utilization.
In my job, I normally support other teams to complete their pipelines, primarily to implement them on deploy part. For my team, I engage to draft the pipelines and simplify the processes.
In the creating of a pipeline I find some obstacles. Ones of them are the regulations that want to minimize the risk introducing complexity in the processes. For example the Separation of Duties which involves several stakeholders in a process of releasing.
An other obstacle is the use of tools officially acknowledged by the company that are not simply integrable in the process.
In conclusion, I know that the journey to DevOps is still long, but I am fascinated by this world and I want to keep learning new things.