Continuous Integration and Continuous Delivery (CI/CD) has long been the cornerstone of modern software development, enabling teams to automate the build, test, and deployment processes. However, the traditional CI/CD pipeline, where a single system orchestrates both building and deploying, can become a bottleneck, especially in complex, cloud-native environments.
This article explores the limitations of traditional CI/CD and introduces a more robust and scalable approach: separating the CI process from the CD process using GitOps. I’ll examine the benefits of this evolved strategy, including improved resource utilization, enhanced rollback capabilities, and a declarative approach that aligns perfectly with modern infrastructure.
The Limitations of Traditional CI/CD
In the “old days” of CI/CD, infrastructure management was often a separate concern, handled through configuration management tools like Ansible, Puppet, Chef, or even manual scripts. Changes were often applied on-demand, leading to configuration drift and the need for hotfixes. Even with the adoption of DevOps practices and teams, a clear separation between development and operations often persisted.
The CI/CD pipeline itself, responsible for both building and deploying, became a single point of entry with custom logic and an imperative approach. While CI took care of testing, building artifacts, and creating container images, CD often involved automatic deployments to non-production environments and manual approvals for production.
However, this classical CI/CD pipeline approach, which combines building and deploying into one automated flow, has several critical shortcomings:
- Difficult and Incomplete Rollbacks: Traditional CD pipelines often construct deployment manifests “on the fly” and immediately deploy them to clusters. This makes rollbacks complex and incomplete, as there’s no complete audit trail of the deployment process. Often, the manifests themselves are not versioned, making true rollback impossible.
- Tight Coupling: The tight coupling between building and deploying reduces flexibility and increases complexity. Changes to the deployment process often require changes to the CI pipeline, and vice versa.
- Imperative vs. Declarative: Using an imperative approach with declarative systems like Kubernetes is inherently problematic. Why manage a declarative system with imperative commands? The same applies to other declarative tools like Terraform/OpenTofu.
- Deployment Disconnect: Deployments are often disconnected from platform changes. The platform exists for the application, and changes are often related. It’s easier to diagnose and revert issues if application deployments and platform changes are managed in the same way – ideally through GitOps.
A New Approach: CI & CD with GitOps
Instead of a monolithic CI/CD pipeline, we can separate the build and deployment processes:
- Dedicated CI for Building: Leverage your existing CI engine (e.g., Jenkins, GitHub Actions, GitLab CI) to focus solely on building, testing, and creating artifacts (container images, binaries, etc.).
- GitOps-Powered CD for Deployment: This is where the real improvement lies. Define the desired state of your applications in a Git repository and use GitOps tools to automatically synchronize that state with your environment. The Git repository becomes the single source of truth for your application deployments.
- Unified Management: Unify the management of application deployments with platform changes. Because some platform changes depend on application changes (e.g., through explicit versioning of platform components), managing them together simplifies operations, diagnostics, and rollbacks.
Who Benefits from This Approach?
To be honest, the biggest benefits will be seen within large organizations with many complex projects, multiple teams, departments and dozens if not hundreds of applications. They will benefit from the increased control and auditability that GitOps provides. These features are invaluable when managing deployments at scale.
I would also advise this approach for small startups with greenfield projects, as they can start delivering their services much faster and reduce their technical debt from the very start. This will allow them to build a scalable and reliable deployment process from the ground up, and thus innovate and grow faster.
Benefits of the New Approach
- Time Savings: Faster release cycles and reduced Time To Market (TTM). This is crucial, most important and visible benefit.
- Increased Transparency: Every change is tracked in Git, providing a clear audit trail of all deployments.
- Simplified and Complete Rollbacks: Reverting to a previous state is as simple as reverting the corresponding commit in the Git repository and letting the GitOps engine synchronize the changes.
- Everything as Code: Supports the “Everything as Code” philosophy, preventing the chaos and inconsistencies that traditional CI/CD pipelines can introduce.
How to Implement CI & GitOps
Implementing CI & GitOps is surprisingly straightforward:
- Choose a Git Provider: Select a Git provider (GitHub, GitLab, Bitbucket) and establish a clear repository structure, including a dedicated “source of truth” repository for GitOps-managed deployments.
- Configure Your CI Pipeline: Use your existing CI engine (Jenkins, GitHub Actions, GitLab CI) to build container images, test applications, and generate deployment manifests. Ideally, the CI pipeline should not only create commits but also create new branches and automatically generate pull requests for those changes.
- Integrate a GitOps Engine: Connect everything using a GitOps engine. Argo CD is a popular and powerful solution for most use cases. Consider Flux CD for smaller environments or when you need a lightweight solution. The GitOps engine will automatically apply changes to your platform based on the files in the Git repository.
Is It Easy?
While adopting this approach may present initial challenges, the long-term benefits – reduced operational overhead, increased reliability, and faster TTM – make the investment worthwhile.
Experienced teams will find it easier to manage, and it’s essential for teams looking to avoid the constant frustration and inconsistency of traditional environments.
Conclusion
By separating the CI and CD processes and embracing GitOps, organizations can overcome the limitations of traditional CI/CD and achieve a more scalable, reliable, and auditable deployment pipeline.
This evolved approach aligns perfectly with the principles of Cloud Native development and enables teams to deliver software faster and more efficiently.
Comments