CI/CD and GitOps solve different problems, but they work best together.
CI systems validate and build your code. GitOps tools like Argo CD and Flux handle deployment by continuously reconciling your cluster state with what’s defined in Git.
When integrated correctly, CI builds artifacts and updates manifests, while GitOps handles the actual deployment. This separation increases reliability, auditability, and deployment safety.
This article explains how to integrate CI/CD with GitOps tools in a clean, scalable way.
CI vs GitOps: Clear Separation of Responsibilities
Before integrating, it’s important to understand the separation of concerns.
CI is responsible for:
- Running automated tests
- Building artifacts (Docker images, binaries)
- Producing versioned releases
- Updating deployment manifests
GitOps is responsible for:
- Watching Git repositories
- Reconciling cluster state with declared configuration
- Applying Kubernetes manifests
- Handling rollbacks
The key principle: CI does not deploy directly to the cluster.
Instead, CI updates Git. GitOps deploys.
Step 1: Build and Push an Artifact in CI
A typical CI pipeline for a containerized app might:
- Run tests
- Build a Docker image
- Tag it with a commit SHA
- Push it to a registry
Example CI block:
blocks:
- name: Build and Push Image
task:
jobs:
- name: Build
commands:
- checkout
- docker build -t myapp:$SEMAPHORE_GIT_SHA .
- docker push myapp:$SEMAPHORE_GIT_SHA
At this point, you have a versioned artifact in a container registry.
Nothing has been deployed yet.
Step 2: Update Kubernetes Manifests in Git
Instead of running kubectl apply from CI, the pipeline updates the image tag in a Git repository that defines the Kubernetes manifests.
Example deployment.yaml before:
spec:
containers:
- name: myapp
image: myapp:old-tag
After CI updates it:
spec:
containers:
- name: myapp
image: myapp:3f8a92d
CI commits and pushes this change to a dedicated GitOps repository.
This repository is watched by Argo CD or Flux.
Step 3: GitOps Applies the Change
Argo CD or Flux detects the updated manifest and reconciles the cluster state.
Deployment happens automatically, but it is:
- Driven by Git
- Auditable
- Declarative
- Reversible
This model ensures that:
- The cluster state always matches Git
- Manual drift is corrected
- Rollbacks are Git reverts
Why This Model Scales Better
Large organizations prefer CI + GitOps separation because:
- CI systems are optimized for builds, not cluster state management
- Deployment logic is declarative, not imperative
- Security boundaries are cleaner
- Access control is simplified
CI does not need direct cluster credentials in production. It only needs permission to update Git.
Environment Promotion in GitOps
In GitOps workflows, environments are typically separate directories or repositories:
- /environments/dev
- /environments/staging
- /environments/prod
Promotion happens by:
- Merging changes from dev to staging
- Or updating image tags in a higher environment
- Or cherry-picking specific commits
This keeps environment transitions explicit and reviewable.
Handling Rollbacks
Rollback becomes simple:
- Revert the Git commit that changed the image tag
- GitOps reconciles back to the previous version
No need to manually redeploy from CI.
Integrating Semaphore with GitOps
Semaphore fits naturally into this model:
- Use Semaphore for test automation and artifact builds
- Use workflows and parallel blocks to optimize build time
- Push updated manifests to a GitOps repository
- Let Argo CD or Flux handle cluster reconciliation
Semaphore documentation on workflows can help structure multi-stage pipelines.
Deployment patterns and environment configuration are documented here.
Common Mistakes When Combining CI and GitOps
Deploying Directly from CI
Running kubectl apply from CI bypasses GitOps. This breaks the declarative model and creates drift.
Not Versioning Manifests
If manifests are not version-controlled separately, rollback becomes harder.
Using Mutable Image Tags
Always use immutable tags (commit SHA or version numbers). Avoid latest.
Giving CI Full Cluster Access
In a proper GitOps model, CI does not require production cluster credentials.
Summary
Integrating CI/CD with GitOps tools like Argo CD or Flux means separating concerns clearly:
- CI builds and validates artifacts
- CI updates Git manifests
- GitOps reconciles cluster state
This model improves reproducibility, auditability, and operational safety. It scales better than direct deployment from CI and aligns with modern Kubernetes best practices.
FAQ
Yes. GitOps handles deployment, but CI handles testing, artifact creation, and manifest updates.
No. In a GitOps model, CI updates Git and GitOps handles deployment.
Many teams use separate repos for application code and deployment manifests, but it depends on team structure.
Primarily yes, but the principles can apply to other declarative infrastructure systems.
Want to discuss this article? Join our Discord.