All Posts
12 Nov 202512 min readIntermediate

Why Do We Need Argo CD If We Already Have Jenkins?

Part of Platform Engineering

  • GitOps
  • Kubernetes
  • CI/CD
  • Jenkins

Every platform team eventually gets this question in a Slack thread: we already pay for Jenkins, we have dozens of pipelines, why do we need Argo CD too? The short answer is that they solve different problems. Jenkins is a CI engine that builds artifacts and runs workflows. Argo CD is a continuous reconciliation controller that keeps your Kubernetes cluster aligned with Git.

At Edmingle, we run Jenkins for build, test, and image publish. Argo CD watches the deployment repo and applies what Git says should be running. Neither replaces the other. Confusing them leads to kubectl apply in CI pipelines, drift nobody notices, and rollback stories that start with 'someone ran a hotfix on prod.'

What Jenkins Actually Owns

Jenkins excels at imperative workflows: checkout code, run unit tests, scan dependencies, build a Docker image, push to ECR, maybe trigger a downstream job. It is event-driven. Something happens (a push, a cron, a manual click), and Jenkins executes a sequence of steps.

That model works well for CI because CI is inherently procedural. You need branching logic, credentials, parallel stages, and artifact promotion gates. Jenkins has decades of plugin ecosystem for exactly this.

pipeline {
  agent any
  stages {
    stage('Test') {
      steps { sh 'npm test' }
    }
    stage('Build') {
      steps {
        sh 'docker build -t $ECR_REPO:$GIT_SHA .'
        sh 'docker push $ECR_REPO:$GIT_SHA'
      }
    }
    stage('Update Manifest') {
      steps {
        sh '''
          yq -i '.spec.template.spec.containers[0].image = "'$ECR_REPO:$GIT_SHA'"' k8s/deployment.yaml
          git commit -am "deploy $GIT_SHA"
          git push
        '''
      }
    }
  }
}

Notice what Jenkins does at the end: it mutates Git. That is a handoff, not deployment. Whether the cluster actually runs the new image is a separate concern.

What Argo CD Actually Owns

Argo CD continuously compares desired state (Git) with live state (the cluster) and reconciles the difference. It is declarative and pull-based. The cluster asks 'what should I be?' rather than CI pushing 'here is what you should become.'

Git Repo (desired)          Argo CD              Kubernetes (live)
─────────────────         ─────────            ─────────────────
deployment.yaml    ──►    diff + sync    ──►   Deployment/Pods
service.yaml       ──►    health check   ──►   Service/Ingress
configmap.yaml     ──►    prune          ──►   ConfigMaps

When someone kubectl edits a Deployment directly, Argo CD flags OutOfSync. When you revert Git, the cluster follows. That is the core GitOps property: Git is the source of truth, not the last person with kubeconfig access.

Argo CD also gives you application-level visibility: sync status, health, diff view, rollback to a previous Git commit. Jenkins job logs do not replace that.

The Anti-Pattern: Jenkins Deploying Directly to K8s

I have seen teams wire Jenkins to run kubectl apply or helm upgrade against production. It works until it does not.

  • CI credentials need cluster-admin or equivalent. That is a large blast radius for a build server.
  • Deploys are push-based and tied to pipeline timing. A failed apply halfway through leaves ambiguous state.
  • No continuous drift detection. Someone patches a ConfigMap at 2 AM and nobody knows until the next deploy overwrites it.
  • Rollback means re-running an old pipeline or manual kubectl, not reverting a Git commit.

The fix is not 'delete Jenkins.' The fix is a clean boundary: Jenkins produces immutable artifacts and updates Git. Argo CD deploys from Git.

How They Fit Together in Practice

ConcernJenkinsArgo CD
Build and test codeYesNo
Push container imagesYesNo
Deploy to KubernetesNo (updates Git only)Yes
Detect config driftNoYes
Application health dashboardLimitedYes
Rollback via Git revertIndirectNative

A typical flow at Edmingle: developer merges to main, Jenkins runs tests and pushes api-service:abc123f to ECR, a bot or pipeline stage bumps the image tag in the gitops repo, Argo CD syncs within seconds, and the Deployment rolls out with whatever strategy we defined in the manifest.

For preview environments, Argo CD ApplicationSet can generate apps per branch while Jenkins still builds the image. Same split, different trigger.

When You Might Skip Argo CD

Argo CD is not free operational complexity. You need a GitOps repo structure, RBAC, secrets management (Sealed Secrets, External Secrets, or SOPS), and team buy-in that Git is the deploy interface.

If you run a handful of services on ECS or bare VMs with no Kubernetes, Argo CD adds nothing. If you have one cluster and one engineer who deploys twice a month, a well-scoped Jenkins deploy stage might be fine until pain appears.

The inflection point is usually multiple teams, multiple clusters, or audit requirements around who changed prod and when. That is when continuous reconcile pays for itself.

Engineering Takeaways

  • Jenkins is CI: build, test, publish artifacts. Argo CD is CD for Kubernetes: reconcile cluster state from Git.
  • Do not give Jenkins direct kubectl access to production. Update Git; let the GitOps controller deploy.
  • GitOps gives you drift detection, auditable rollback, and a single source of truth Jenkins logs cannot provide.
  • The handoff between CI and CD should be an immutable image tag committed to a deployment repo.
  • Argo CD adds value proportional to cluster count, team count, and compliance needs-not replace Jenkins on day one.
  • Treat 'why do we need both?' as a teaching moment about imperative vs declarative deployment models.

Trade-offs I Would Consider

Option: Jenkins-only with kubectl deploy

  • Pros: One tool, familiar to most teams, fast to set up for small fleets.
  • Cons: Push-based deploys, credential sprawl, no drift detection, painful rollbacks under pressure.

Option: Jenkins CI + Argo CD GitOps

  • Pros: Clear separation of concerns, auditable deploys, continuous reconcile, safer prod access model.
  • Cons: Two systems to operate, GitOps repo discipline required, initial learning curve for app teams.

What I Would Do in Production

Keep Jenkins focused on CI: test gates, image build, tag promotion. Never kubectl apply to prod from a pipeline.

Use a dedicated gitops repository with environment overlays (Kustomize or Helm). CI opens a PR or commits a tag bump; humans or policy approve.

Run Argo CD in HA mode on the management cluster or alongside workloads with AppProject RBAC so teams only sync their namespaces.

Enable auto-sync for non-prod, manual or PR-gated sync for prod. Wire Slack notifications on OutOfSync and Degraded.

Document the contract for app teams: 'Your Jenkins job ends when the image is in ECR and Git is updated. Argo CD owns everything after that.'

FAQ

Q: Can Argo CD replace Jenkins entirely?

No. Argo CD does not run your unit tests or build Docker images. It deploys what Git declares. You still need a CI system unless you move builds elsewhere (GitHub Actions, Tekton, etc.).

Q: We use GitHub Actions instead of Jenkins. Same answer?

Yes. The split is CI vs GitOps CD, not Jenkins vs Argo CD. Actions builds and updates Git; Argo CD reconciles the cluster.

Q: What about Flux instead of Argo CD?

Same category. Flux and Argo CD are GitOps controllers. Pick based on team preference, UI needs, and multi-cluster patterns. The Jenkins question applies identically.

Q: Does Argo CD slow down deploys?

Sync is typically seconds after Git updates. The bottleneck is usually image build and test in CI, not Argo CD reconcile.

Q: How do we handle secrets?

Never commit plain secrets. Use External Secrets Operator, Sealed Secrets, or SOPS-encrypted files in Git. Argo CD syncs references; secrets resolve at runtime.