Over the last couple of years, automation in the form of continuous integration, delivery, and development (CI/CD) has become increasingly popular and important. Its rise in popularity is related to its ability to create a seamless and efficient DevOps process, from writing code to deploying it to production. This encourages higher quality application development, faster release times, and improves the security and stability of delivery capabilities. As described in a previous article, the result of a recent project with our client CC4ALL was their transition from a monolithic to a microservices driven architecture. Although this upgrade has ensured greater efficiency, application flexibility, and improved performance for them, it has also had a particular impact on the way their CI/CD pipelines are defined.
So, how have we adopted CI/CD in our project with CC4ALL and what is the effect of CI/CD pipelines?
Why CI/CD pipelines were implemented with CC4ALL
CI/CD are an essential part of our DevOps approach and practice to enable continuous delivery of value. A CI/CD pipeline is a series of steps that need to be performed in order to deliver a new version of a software. Their true value is in introducing ongoing monitoring and automation to improve the process of application development, delivery, and deployment. Whilst “CI” always refers to continuous integration, “CD” refers to continuous delivery and/or deployment (related concepts that are sometimes used interchangeably).
The implementation of CI/CD pipelines have been on the rise over the past few years due to the benefits and advantages they provide. Back in 2017, a survey of DigitalOcean’s community found 42% used CI/CD. Of those who did not use CI/CD, 38% had plans to implement it in the future and 46% did not believe these methods were necessary for their workflow. It’s not easy to define the depth of CI/CD adoption and implementation today since teams do not necessarily use all three concepts. A 2019 survey by mabl of 500 software testers revealed that 53% of teams use continuous integration, while only 38% have continuous delivery and 29% continuous deployment. Regardless, it’s undeniable that interest in CI/CD has increased steadily over the years, as exemplified by Google search trend results.
In our project with CC4ALL, the milestone of transitioning towards a microservices architecture was already underway. Although there are many approaches to using containers and CI/CD pipelines together, CC4ALL uses microservices architecture with deployment in Azure Kubernetes Services. The greatest challenge was the prolonged period it took to define the pipelines for this configuration. Our DevOps team spent weeks solely on this complex and time-consuming task. But the impact and benefits of the final result was well worth the time and effort. Automation of the whole process has eliminated repetitive manual processes and the team has more time to focus on offering new and improved versions, without downtime, in a short period of time (minutes rather than hours or days).
Let’s dive a little deeper into what each part of the CI/CD pipeline means and how it has affected CC4ALL.
Continuous Integration
Continuous integration (CI) is the practice of automating the integration of code changes from multiple contributors into a single software project. It’s one of the most important DevOps practices since it allows developers to merge code changes frequently into a central repository where build, tests and other steps will then run.
The main purpose of the CI pipeline is to generate a build artifact that packages the components of the application. In the case of CC4ALL, the artifacts are versioned Docker container images that represent each microservice of the platform, which are then pushed to Azure Container Registry. The mechanisms that ensure the integration of code changes are compiling, unit testing, and static code analysis. If any of the steps fail, the process stops and no artifacts are generated, which enables the team to discover and fix the root cause.
Here’s a list of CI best practices:
- fix the broken builds
- run tests locally before committing
- keep the builds fast
- commit early and commit often
Continuous Delivery
Continuous delivery is an extension of continuous integration. It automatically deploys all code changes to a testing and/or production environment after the build stage. This means that on top of automated testing, there is an automated release process and an application can be deployed at any time by clicking a button.
With modern platforms such as Kubernetes, the separation of environments might not be physical when compared to legacy or traditional machine-based platforms. A namespace (software separation) might be all that separates different testing and/or acceptance environments.
For CC4ALL, the continuous delivery pipeline relies on the Azure DevOps server, which coordinates all the deployment tasks. Since the platform uses Kubernetes to orchestrate the deployment of microservices, tasks only consist of connecting to the Kubernetes cluster and then applying the Helm charts that describe the new version of the application. The lower the number of steps to deploy a new release, the better.
Continuous Deployment
Continuous deployment goes one step further than continuous delivery. With this practice, every change that passes all stages of the production pipeline is released to customers. There’s no human intervention and only a failed test will prevent a new change from being deployed to production. It’s an excellent way to accelerate the feedback loop with customers and take pressure off the team.
Here are a few continuous deployment best practices:
- ensure the number of steps to deploy the software are minimal
- use rolling deployment that enables incremental replacement of old versions
- maintain the staging environment as closely as possible to the production environment
- avoid using environment-specific builds
How it all comes together in software delivery
CI and CD are often mentioned together since they are different yet related stages in modern software delivery pipelines. The CI pipelines generate an artifact that is then used by a delivery pipeline to make the new version of an application available. Automating the whole pipeline ensures a quick feedback loop that enables the early detection of possible issues and a faster release rate. Using modern tools (such as Azure DevOps, Kubernetes, and DevOps practices) also makes it easier than ever to set up CI/CD pipelines, even in the case of complex architectures like microservices.
By combining a microservices architecture with CI/CD pipelines, CC4ALL has enjoyed the overall impact of a more advanced, high-performance application. Since all the processes are automated, the team can scale up and update the app without downtime.