The two elements of CI/CD — continuous integration and continuous delivery — are about achieving a short and regular release cycle by frequently releasing code to a main branch. CI/CD keeps software delivery agile, promotes innovation and cuts through the risks of monolithic delivery.
With CI/CD practices, the development team’s routine tasks will be automated as much possible. It is simple in theory — but can be very complex in practice, especially for modern development teams working with challenging software products.
A quick note: «CD» is often interchangeably defined as «continuous deployment» or «continuous delivery». The differences are slight — sometimes, «continuous delivery» can refer to different staging environments, whereas «deployment» is normally about production only. In this article, I will make it clear which I am referring to.
Five Elements of Good CI/CD
Visibility. At any time, the whole development team should know exactly which staging environment code is in.
Feedback. When developers push code to the master branch, they need to know instantly if it has broken something, and all the necessary details of the issue.
Proof of continuous deployment. The evidence of good CI/CD will be regular high-quality feature releases to the end users.
Cost-saving. In comparison to engineering without CI/CD (which heavily involves automation), CI/CD environments should save computing costs.
Reliability. 99,99%+ reliability of the solution is an indicator of good CI/CD that cannot be argued with — anything below this points to issues with tooling or processes.
Modern CI/CD approaches provide solutions to the most common setup challenges.
Challenge 1: Manual Configuration.
Manually setting up development environments can easily become unmanageable when requirements scale. Not only is this time-consuming, but it’s easy to lose track of organisation, which can lead to poor setups that drive billing through the roof.
Creating an automated build server which can support the declarative configuration of CI/CD pipelines (like Jenkins Pipelines, GitlabCI, Azure DevOps etc.) will remove the manual element from this issue, reducing the risk of error. It also means teams can focus on code rather than ongoing support of the environment, so they can get code out the door at a faster pace.
Challenge 2: Lack of Visibility.
When it comes to monitoring, a 20/20 view of system performance is necessary, because it’s pretty much guaranteed that the one part that is hidden will cause everything to break at some point. A good monitoring setup is part of the key to 99,99%+ availability — it is how teams ensure changes can be immediately reverted if necessary. Quality visualisations allow development teams to understand what stage code is at — without this, they can be one step behind critical issues.
Solution: Great monitoring setup.
This is the key to diagnosing issues as they happen, and it’s especially necessary in high-volume environments where developers are committing code at a fast pace. The success formula is dependent on the environment, but it’s best to have an automated setup which can offer an accessible visual of performance across all application layers. Example tools that are commonly used are GitlabCI or Jenkins 2 — both offer a comprehensive monitoring setup.
Challenge 3: Resource Utilisation.
A common setup error finds resources being consumed regardless of if they are being used by a service. This is the culprit of sky-high costs in CI/CD setups. Resources cannot be switched off due to the inability to predict when they are required. In many cases this ties in with the issues surrounding complex manual configuration scripts. Spaghetti code setups are notoriously complex to detangle, especially when outages are a risk factor, so often companies simply eat the cost.
Solution: Dynamic Resource Allocation.
Docker and Kubernetes are the dream duo for reducing costs, as well as most other challenges. If we need to run something, Kubernetes (the «helmsman» of containers») can orchestrate allocation of resources accordingly. It’s an easy way to dynamically allocate resources to pipelines and dispose of them when the job is done, creating a very streamlined and cost-effective process.
The Ultimate Solution: Preparation.
From the very beginning, before a line of code is written, teams should plan CI/CD into their approach. They should know exactly how code will be delivered to end-users, as the preparation will also indicate how effective the system should be. Essentially, by preparing, we can overcome obstacles which would be otherwise difficult. The process has now become much easier thanks to technologies such as containers which enable CI/CD to be set up quicker by the development team. The cross-functional team can set it up by themselves without the help of a DevOps team, which also accelerates the process, so much so that everything can be set up in under an hour.