💡 Introduction
When teams talk about migrating from Jenkins to ArgoCD, they often discuss the tools, not the transformation. You’ll find plenty of “how to install” guides — but almost no one writes about what really happens when you shift from pipelines to GitOps.
In this blog, I’ll share real migration lessons learned during a multi-cluster move from Jenkins-based CD pipelines to GitOps with ArgoCD — lessons that include YAML comparisons, mindset changes, and the unexpected issues that never make it to documentation.
Because the truth is simple:
GitOps isn’t about tools — it’s about a mindset shift from execution to declaration.
🧩 Why We Moved: From Imperative Pipelines to Declarative State
Our Jenkins setup worked — it built, tested, deployed. But at scale, we faced:
- ❌ Environment drift — dev and prod rarely looked identical.
- 🔍 Visibility gaps — Jenkins UI didn’t tell us what the cluster actually ran.
- ⚠️ RBAC sprawl — pipelines had over-permissive service accounts.
- 🌀 Manual gates — too many approvals delayed releases.
We needed a source of truth for deployments — something that could detect drift, self-heal, and show what was really running.
That’s where ArgoCD and GitOps entered the picture.
🗺️ Migration Roadmap
We didn’t just “switch tools.” We migrated mindsets.
Here’s the phased roadmap we used — practical and repeatable.
| Phase | Description | Key Focus |
|---|---|---|
| Phase 0: Assessment | Inventory all Jenkins jobs, environments, and dependencies. | Identify what stays in CI vs moves to CD. |
| Phase 1: Pilot | Set up ArgoCD for a non-critical app. Keep Jenkins for builds. | Validate GitOps flow. |
| Phase 2: Expansion | Gradually migrate staging and prod apps. Add ApplicationSets. | Multi-cluster, RBAC design. |
| Phase 3: Governance | Create ArgoCD Projects, enforce sync policies. | Standardization, observability. |
| Phase 4: Culture | Train teams, measure drift, celebrate automation. | Shift from “click deploy” → “merge manifest.” |
📊 Featured Image:
Include the previously generated visual roadmap + YAML comparison as the header image.
⚙️ YAML Comparison: Jenkinsfile vs ArgoCD Application
The biggest mental shift?
You move from defining steps to defining state.
🧱 Jenkins Declarative Pipeline
pipeline {
agent any
environment {
IMAGE = "myapp:${env.BUILD_NUMBER}"
REGISTRY = "registry.mycorp.com/myapp"
}
stages {
stage('Checkout') {
steps {
git url: 'https://git.mycorp.com/myapp.git', branch: 'main'
}
}
stage('Build & Push') {
steps {
sh "docker build -t ${REGISTRY}:${BUILD_NUMBER} ."
sh "docker push ${REGISTRY}:${BUILD_NUMBER}"
}
}
stage('Deploy to Dev') {
steps {
sh "kubectl set image deployment/myapp myapp=${REGISTRY}:${BUILD_NUMBER} -n dev"
}
}
}
}
🧭 ArgoCD Application YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: myapp-project
source:
repoURL: 'https://git.mycorp.com/myapp.git'
targetRevision: main
path: deployments/overlays/dev
destination:
server: 'https://kubernetes.default.svc'
namespace: dev
syncPolicy:
automated:
prune: true
selfHeal: true
🔍 Key Takeaways
| Jenkins | ArgoCD |
|---|---|
| Defines how to build & deploy | Defines what to deploy |
Uses shell commands (kubectl) | Uses Git repo + reconciliation |
| Imperative flow | Declarative state |
| Manual approvals | Git-based promotions |
| CI + CD tightly coupled | CI (build) and CD (deploy) separated |
🧨 Common Issues (and How We Fixed Them)
1. Environment Drift
- Issue: Teams still used
kubectl patchmanually. - Fix: Enabled
selfHeal: truein ArgoCD, restricted direct cluster edits, enforced Git PRs for changes.
2. RBAC Mismatches
- Issue: Jenkins service accounts had broad cluster access.
- Fix: Created ArgoCD Projects with role-based sync and namespace boundaries.
3. Visibility Gaps
- Issue: Teams couldn’t see full flow from build → deploy → cluster.
- Fix: Built dashboards combining Jenkins (build), ArgoCD (sync), and Prometheus (health).
4. Legacy Logic
- Issue: Complex Groovy scripts in Jenkins didn’t translate easily.
- Fix: Extracted business logic into CI, converted deployment logic into Helm/Kustomize overlays.
5. Cultural Resistance
- Issue: Developers were comfortable “clicking deploy.”
- Fix: Held GitOps workshops. Showed how a merge auto-deploys. Metrics spoke louder than words.
🧠 Lessons Nobody Writes About
- Drift is cultural, not technical — unless you restrict manual edits, GitOps won’t save you.
- RBAC matters more than you think — ArgoCD will happily deploy everywhere if misconfigured.
- Visibility ≠ simplicity — You’ll need to stitch Jenkins, ArgoCD, and cluster metrics for a full picture.
- CI/CD separation is liberating — Jenkins focuses on building. ArgoCD focuses on syncing.
- GitOps is a mindset — It’s about declaring desired state, not scripting actions.
🧭 The Mindset Shift: From Execution → Declaration
Old World: “Run Jenkins job, deploy manually.”
New World: “Merge to main, ArgoCD syncs automatically.”
Once teams internalize this, magic happens:
- Fewer production surprises
- Transparent audit trails
- Predictable, repeatable deployments
You stop chasing what happened and start trusting what’s declared.
🚀 Final Thoughts
Migrating from Jenkins to ArgoCD isn’t just a tool swap — it’s an organizational evolution.
Start small, migrate gradually, and make Git the single source of truth.
Let Jenkins handle what it’s best at — building and testing, while ArgoCD ensures your clusters reflect your code.
Once that shift clicks, you’ll realize why the best DevOps transformations aren’t about pipelines — they’re about people, processes, and declaration.