continuous delivery (CD) CI/CD pipeline security: Know the risks and best practices
Definition

What is continuous integration (CI)?

Continuous integration (CI) is a software development practice in which frequent and incremental changes are routinely added or integrated to the complete codebase immediately after the changes and additions are tested and validated.

The CI paradigm fulfils several important goals. First, CI provides rapid feedback so that, when a defect is introduced into the codebase, it's identified and corrected as soon as possible. CI helps to keep the entire project's codebase current, which is vital when multiple developers are working on the same codebase simultaneously. Finally, CI practices make the software development process faster and more predictable by working in small iterations where development cycles and workflows are easier to manage.

The CI process develops the following pattern:

  1. A software developer pulls a copy of the code -- or a portion of the larger codebase, such as a module -- from a central repository.
  2. The developer makes changes, corrections and additions to the code. Such changes might take several minutes to several hours depending on the number and scope of changes.
  3. The software developer merges or commits their code changes back into the central repository. The merge action triggers a series of activities, including automated code builds and testing -- usually, unit tests or integration tests.
  4. Newly developed code is sent to a shared repository using a version control system, like Git. These changes are saved as a copy or a branch that's separate from the current release or production version of the code.

Merging and testing have one of the following two possible outcomes:

  1. If the automated testing process finds a bug, the CI service blocks the software development iteration from progressing further, and the development team receives a report. The software issues can then be addressed quickly. These code integrations are made frequently, sometimes multiple times per day.
  2. If the automated testing process completes successfully, the branch might be subject to more extensive testing, such as user acceptance testing (UAT), or be staged for possible release or deployment into a production environment. In other cases, the successful branch might receive additional development work through subsequent iterations.

The process where a successful build is staged for further testing and possible deployment is called continuous delivery (CD). This common practice is used to expand on CI after the build stage by deploying those code changes to a testing or production environment as appropriate. The two practices go hand in hand and are commonly referred to as CI/CD.

Some development paradigms automatically deploy all successful builds as a matter of standard practice. This is called continuous deployment. The principal difference between continuous delivery and continuous deployment is that delivery offers the potential for deployment -- often decided by a human -- while deployment is typically a standard or obligatory part of each development cycle.

CI originated from within the extreme programming paradigm, which is a subset of the Agile methodology, but the principles can be applied to any iterative programming model, such as DevOps. Traditional development approaches, such as the Waterfall model, can also benefit from the use of CI methods for the construction or build stage.

The importance of continuous integration

Working on code for an extended period and only merging it to a central repository when completed makes the merging process much more challenging and time-consuming. This process can result in more bugs, which take more time to comb through and fix. CI paradigms rely on much faster and smaller-scale changes.

Regularly merging small code changes instead is typically a more accurate and safer process. If any bugs are found in the merging process, they're easier and faster to find. The shorter feedback loop of CI also enables more code iterations. Ultimately, CI techniques can help to create better quality code in less time than traditional methodologies.

CI also makes the process much faster through the addition of automated builds and tests. CI tools can monitor the central code repository and accept or reject code commits.

Benefits of continuous integration

When it incorporates CI into the development process, a software development team can bring worthwhile benefits to an organization, including the following:

  • Shorter and less disruptive code integrations. CI features less code integrated at a time more frequently than other development approaches. Similarly, reverted changes are less disruptive, as only isolated changes are released at once.
  • Faster and easier bug detection. If a bug surfaces, it will most likely be in the last integrated batch of code. This benefit is a result of increased code visibility, as software developers constantly add to the codebase.
  • Feedback. CI enables continual feedback on changes, which can improve product performance and product quality over time. The process makes it faster and easier to respond to feedback.
  • Productivity. Software developers don't have to run a test with every code merge, as that process is automated. They can instead spend more time on other tasks.
  • Testing. Tests run in CI help verify code correctness, validate application behavior, test code for security, and run automated unit, integration or regression tests.
  • Collaboration. CI through central repositories enables many developers and managers to see code, view test results and work together to ensure that development is proceeding efficiently. Product features and changes can be handled with less disruption. New ideas and suggestions can readily be shared across teams.

How continuous testing affects continuous integration

Continuous testing is a continual and often automated software testing process where different test types are performed in the software development pipeline. Continuous testing is implemented to find bugs as soon as they appear in a codebase. The continuous testing process uses automated tools that check code quality, verify proper security, and then load premade test scripts and data sets to validate source code efficiencies and look for bugs. Each code change in continuous testing starts a set of tests to identify potential issues in the code. Feedback is provided to the relevant teams if an automated test fails.

Continuous testing is a critical component behind CI, as well as in the CI/CD process. Continuous testing accelerates software development time by improving code quality, while providing important feedback early in the software development lifecycle (SDLC) process.

In a broader sense, CI testing serves the same vital purpose as testing in Waterfall and other traditional development paradigms. The principal difference with CI is that testing protocols and goals are well defined early in the software's design and tests are implemented automatically with little -- if any -- human intervention. The rapid, cyclical nature of CI often results in many repeated tests, which can help build confidence in the evolving codebase.

However, automated testing isn't perfect, and subsequent manual testing, such as UAT, might be appropriate once automated test results are successful. The key here is to configure and run tests that are appropriate for the code being developed -- one testing regimen might not be suitable for every code project.

Continuous integration best practices

Continuous integration offers significant benefits to practitioners, but the faster pace demands a greater level of workflow organization and control that can pose challenges to development teams and the overall organization. Best practices associated with CI include the following:

  • Focus on small changes that can be made quickly. Agile and DevOps often reference the adage "commit early, commit often." A central best practice for CI is to focus on small, incremental changes that can be implemented and committed quickly, enabling the change to enter an ongoing pipeline where it can be built, tested, staged and deployed. Taking long periods to tackle massive changes disrupts the workflow pipeline and is contrary to the nature of CI.
  • Optimize the workflow. CI relies heavily on automation, but automation doesn't adjust well on the fly. An efficient and effective workflow pipeline demands careful thought and optimization. Focusing on a single uniform workflow makes the best use of automation and tooling resources and enables all developers to learn and use the same approaches.
  • Include documentation. Change can happen quickly in CI, so each iteration should include attention to documentation that can range from developer notes to application programming interface (API) user guides to consumer how-to documents. This can avoid significant confusion and lost information across frequent iterations.
  • Embrace failure. A central premise of CI is that the quick and frequent process enables developers to easily try new things to innovate. If something doesn't work -- perhaps a unique algorithm approach causes an unwanted rounding error -- it can be quickly documented, changed, adjusted, corrected or rolled back. The freedom to innovate has been a strong driving force behind the adoption of Agile-style development paradigms.
  • Testing should reflect production. Ideally, software should be tested in an environment that's similar -- or even identical -- to the production environment. This includes access to databases with meaningful data; similar network characteristics; services, such as security; and system resources, such as processors and memory, that mirror production. This is the best way to gauge the performance and stability of the build.
  • Maintain security. Developers must adhere to a wide range of security principles that often start with adequate access rights making sure that only authorized developers can access and change code, through proper vulnerability and API security testing in the code, through secure configurations in each deployment. Security practices and configurations should be a key part of the CI pipeline.

CI releases can occur at any frequency, depending on the organization running the project. Generally, organizations that adopt CI release software more frequently than those using other software development processes. Each significant change kicks off a build. A development team incorporates CI for several reasons, including to receive constant feedback on the status of the software. CI detects deficiencies early in development, which makes them less disruptive, less complex and easier to resolve than later in the SDLC.

A development team can use automation in the CI setup process to incorporate integrating code, building, validating and testing, which reduces the time to find bugs and enables faster feedback than when these tasks are carried out manually. Automation tools help teams perform common tests as part of the CI process, such as unit, API and functional tests. A unit test examines the smallest application components. An API test assesses whether an API can reliably perform under its expected load of requests and responses. A functional test typically evaluates larger pieces of the source code to simulate a user workflow or function. With full CI automation, scripts or integration engines manage the movement of new code through tests and build.

This automated approach is often an integral part of a CI/CD pipeline and a DevOps methodology.

An image showing how CI and CD work together.
This shows how continuous integration and continuous delivery fit together.

Continuous integration tools

A development team uses CI software tools to automate parts of the application build and construct a document trail. Many additional tools exist for steps in the CI pipeline, such as version control, testing, build storage and artifact storage.

Based on TechTarget research, examples of CI pipeline automation tools commonly found in enterprise IT shops include the following:

  • Atlassian Bamboo is intended for development teams using Atlassian Bitbucket and Atlassian Jira. Bamboo offers traceability and collaboration, enabling teams to automate building, testing and deployments.
  • Atlassian Bitbucket Pipelines directly integrates into Bitbucket. This tool manages code commits and offers CD capabilities.
  • AWS CodePipeline is Amazon's fully managed cloud-based CI tool. It can automate builds, tests and deployments, while maintaining integration with other Amazon Web Services products, like AWS CodeBuild, AWS CodeDeploy and AWS Lambda, as well as third-party tools.
  • CircleCI integrates with Atlassian Bitbucket and GitLab. This tool is used to automate the steps included in building code, testing updates and deploying applications.
  • GitLab is an open source repository and platform that supports CI/CD. It can run unit and integration tests on multiple machines and split builds to work over multiple machines to decrease project execution times. The software also supports manual deployments for CD to staging and production environments. GitLab also supports integration with tools such as Atlassian Jira, GitHub and Jenkins.
  • Harness is a CD-as-a-service platform that offers a seamless, efficient and intuitive experience intended to speed development, while mitigating release risks. It provides automated rollback, reusable deployment templates and version-controlled development pipelines.
  • Jenkins is an open source CI automation server that can distribute tests and builds over numerous machines. Plugins extend Jenkins' feature capabilities, such as those for automated unit tests and test reporting. A developer can create a project build via specific URLs, commits in a version control system, or a prescheduled and sequential system. Once a system is tested, Jenkins can deploy code with CD. CloudBees enables the use of Jenkins at enterprise scale.
  • JetBrains TeamCity is an integration and management server for CI/CD that lets software developers test code before they commit changes to a codebase. If a test fails, the product sends a notification to users. TeamCity features build grids, which enable software developers to run multiple tests and builds for different platforms and environments. TeamCity supports Atlassian Jira, Docker and other programs.
  • Microsoft Azure Pipelines integrates with Azure and GitHub hosting tools. Azure Pipelines can test code and includes CD and continuous testing features.
  • Semaphore is a high-performance CI platform designed for workflow speed and efficiency using a pull request-based workflow. Semaphore can adjust resources dynamically and execute multiple jobs simultaneously.
  • Spacelift is a versatile CI platform that supports major platforms, including Ansible, AWS CloudFormation, Kubernetes, OpenTofu, Pulumi, Terragrunt and Terraform. It focuses on infrastructure as code.

Continuous integration vs. continuous delivery vs. continuous deployment

CD is a process that occurs after CI, and the two processes are deeply connected -- commonly referred to as CI/CD. CD in CI/CD commonly refers to continuous delivery, but the CD acronym can also be used for continuous deployment -- as both versions of the term are commonly conflated in the following ways:

  • Continuous delivery takes code built in the CI stage and runs various tests for performance, security and usability. These tests are normally automated and include functional, user acceptance, configuration and load testing. If the build passes, it can be deployed with a trigger or button that requires human intervention. However, there's generally no obligation to deploy any successful build.
  • Continuous deployment is the process of automatically deploying the code to customers with zero human intervention. If the finished build passes tests, it deploys straight to production. Here, there's typically a routine obligation to deploy every successful build -- though rollback plans are essential and routinely available as part of the continuous deployment process.

Both continuous delivery and deployment occur after CI, and either one of the two processes is used. The principal difference between continuous delivery and continuous deployment is that continuous deployment automatically deploys each validated build to production. By comparison, continuous delivery only stages the validated build for manual deployment. Continuous deployment, however, should be considered only if a team is confident its code has zero chance of creating an issue.

Learn how to address potential CI/CD implementation problems.

This was last updated in July 2024

Continue Reading About What is continuous integration (CI)?

Dig Deeper on Software development lifecycle