Skip to main content

CI/CD Patterns and Practices

By September 17, 2020November 1st, 2023Blog, Community

Contributed by Tiffany Jachja

In August, I shared a talk on enabling CI/CD through patterns and practices. This blog post summarizes the contents of said talk, informing readers how to enable continuous software delivery.

What is CI/CD?

Software delivery today is not only about getting deliverables into the hands of customers. To succeed, teams and organizations need to deliver value in a quick, safe, and repeatable manner. 

In the DevOps Lifecycle image below, are the actions needed to deliver software:

DevOps infinity sign (Deploy, Operate, Monitor, Plan Code, Build, Test, Release)

Continuous Integration and Continuous Delivery (CI/CD) enables software delivery workflows that involve multiple teams and functions spanning development, assurance, operations, security, and finance teams. Let’s discuss CI and CD in more detail better to understand the goals and therefore patterns for implementation.

Continuous Integration(CI) enables development teams and workflows. The greatest challenge in any development team is managing feature development. Working with code involves developing, merging conflicts, code management, and testing, contributing to long deployment lead times, infrequent deployments, and high change failure rates. The solution is to utilize CI to integrate development changes in an automated fashion, thereby improving feature development’s cadence and process.

Continuous Delivery and Integration, list of products for various categories
(Click image to view full size)

Continuous Delivery (CD) enables operations teams and workflows. The goal is to safely and repeatedly deliver an artifact into a production environment. The CD process helps automate operationalizing services and involves releasing, deploying, and monitoring applications. As we promote an artifact into production or higher environments, we add rigor to the verification process. Adding additional tests to each stage or workflow for an environment allows us to catch issues before getting to a customer. 

Today we’re shifting responsibilities and goals to the left to ensure issues are caught early on in the software delivery process. Production failures and incident management can be otherwise detrimental to a business. 

Pyramid (top: production, middle: non-prodution (dev, test, etc.), bottom: local)

Continuous Integration Practices and Patterns

On the earlier mention of higher environments, every CI/CD process requires an application code build. When you build an application, the source code gets compiled or interpreted and processed into a deployable package. This deployable package is called an artifact in a CI/CD process. Let’s share some practical examples of working with a build process using continuous integration practices.

Automate and test the build

The main practice in a CI pipeline is to automate the build process. This build process can utilize a build tool for a particular codebase. For example, you may use npm to build your node JavasSript applications or Maven and Gradle to build Java or JVM based applications.

Within a build process, you want to ensure you are integrating and performing unit tests, so that builds fail for code that does not meet functional requirements. On the other hand, not having enough unit tests or code coverage can lead to builds that pass but fail down the CI/CD process line. So ensuring you have unit tests is integral to a continuous integration process. They are also cheaper in terms of resources to create and run on a machine. End to end (E2E) are expensive and be difficult to debug as they require multiple services to be running. 

Work the mainline

Another CI practice involves developer teams integrating their code early and often to the main branch of their code repository. This prevents maintenance hell on both feature and main branches as developers progress on feature development. Even if things are still a work in progress, the work can remain invisible to any end-user or tester of the main branch. 

Fix the broken

The third CI practice involves fixing broken builds in the main branch. Continuous Integration assumes your teams are developing on known stable versions of code. 

Continuous Delivery Practices and Patterns

A continuous delivery process ensures that all changes of any kind are safely, quickly, and sustainably delivered to a production environment or into the hands of a consumer. The Continuous Delivery practices and patterns that exist help enable these outcomes.

Automating the Delivery Lifecycle

Every organization has a process for creating and delivering code. A Continuous Delivery pipeline automates this process. Typical delivery responsibilities include provisioning infrastructure, deploying applications, approving deployment changes, quality assurance/testing, and monitoring. Use the CD pipeline as a model for these existing processes.

Infrastructure as code is a practice that helps teams provision, configure, and manage infrastructure resources. 

Defining A Release and Rollback Strategy

A software release is a distribution of software to the consumer. Anytime we release software, we introduce the risk of vulnerabilities, issues, bugs, and non-performant software. There could be any number of reasons for rolling back a deployment or producing a hotfix. 

Define a release strategy that works for your use case to reduce the fear and risk of changes. Some delivery teams will use “Progressive Delivery” strategies to release new features to a customer. Some of those practices include Canary Deployments and Feature Flag management. I recommend learning more about these capabilities and how to enable them with your CI/CD pipeline.

Additionally, rollback strategies tend to mirror release strategies. Whether you decide to keep the current version of your application running while deploying a new instance is up to you. Just ensure you have a rollback strategy that addresses any downtime and data loss. 

Failing Fast in Lower Environments

Organizations that deliver with waterfall methodologies struggle to meet ever-changing landscapes and expectations. Failing fast in a pipeline is similar to borrowing the Agile and lean methodologies becoming the defacto in development teams. What we essentially hope to do is shift responsibilities and activities left within the process of delivering software. A shift left mentality empowers and gives developers the skills and tools to move fast without breaking things.

Most product teams would probably prefer catching an issue before it reaches a customer. Use your pipeline to fail fast in lower environments and to avoid frequent production incidents. 

Takeaways 

Your CI/CD pipeline acts as a model for your SDLC process. It establishes an automated enterprise governance process, ensuring that your organization can actively manage and understand risk. 

This post focuses on existing practices and patterns for you to start building robust and capable CI/CD pipelines. If you are to start with just one practice, I would recommend integrating tests into your CI process. This will lead to additional conversations around automating other relevant software development and delivery workflows.

Key takeaways: focus on tests, simplify dev workflows, automate ops workflows.

And that was all the content from my talk! Thanks to everyone who joined any of the live sessions with this content. The ecosystem for delivery is ever-evolving. I hope to continue to simplify and scale how we do continuous delivery today. If you’re interested in this content, I’ll share a scaling CI/CD framework in my lighting talk at CDCon (Oct 7-8). If you’d like to stay notified of future content and events, I am also on Twitter (@tiffanyjachja) and LinkedIn.