ArgoCD managing itself is peak GitOps

date: Nov 29 2025 4 min read

Make ArgoCD deploy its own updates. Yes, it can delete and recreate itself. No, it does not explode.

.kubernetes.argocd.gitops

You install ArgoCD with Helm. You use ArgoCD to deploy everything else. But who deploys ArgoCD?

You do. Manually. Like a peasant

There’s a better way. Make ArgoCD manage itself. Push a change to your ArgoCD Helm values, and ArgoCD picks it up, diffs it, and upgrades itself. Full GitOps. No kubectl apply. No Helm upgrade commands

The existential question

Can ArgoCD delete and recreate its own pods while processing a sync? What happens when the controller pod restarts mid-reconciliation?

Turns out: nothing bad. ArgoCD is designed for this. The sync state is stored in Kubernetes resources, not in memory. When pods restart, they pick up where they left off. I’ve watched ArgoCD kill its own controller pod and come back 10 seconds later to finish the sync

It’s like a surgeon operating on themselves, except it actually works

The setup

Create an Application that points to ArgoCD itself:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://argoproj.github.io/argo-helm
    chart: argo-cd
    targetRevision: 7.7.5
    helm:
      valuesObject:
        configs:
          params:
            server.insecure: false
        server:
          replicas: 2
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

That’s it. ArgoCD now watches its own Helm chart. Change the version, change a value, push to git. ArgoCD syncs itself

The chicken and egg

How do you create this Application if ArgoCD doesn’t exist yet?

Option 1: Install ArgoCD first with Helm, then create the Application. ArgoCD adopts itself

helm install argocd argo/argo-cd -n argocd
kubectl apply -f argocd-application.yaml

Option 2: Use the App of Apps pattern. Your bootstrap Application creates all other Applications, including the one for ArgoCD

Option 3: Include the Application in the Helm chart itself using server.additionalApplications

I use option 1. It’s simple. The manual install happens once. After that, everything is GitOps

What happens during self-upgrade

  1. You push new values to git
  2. ArgoCD detects drift
  3. ArgoCD starts syncing
  4. Helm upgrade runs, pods get replaced
  5. ArgoCD controller restarts
  6. New controller comes up, checks sync status
  7. Sync completes (or retries if interrupted)

The key: selfHeal: true means if something breaks mid-sync, ArgoCD will retry until it matches the desired state

The fun part

Watch the UI while ArgoCD upgrades itself. You’ll see the pods go yellow (progressing), then the UI disconnects for a few seconds, then it comes back and everything is green

It’s weirdly satisfying. Like watching a robot fix itself

Handling CRDs

ArgoCD CRDs need special attention. If you upgrade CRDs through the Application, make sure the CRDs are applied before the controller tries to use them

The Helm chart handles this with a pre-install hook. But if you’re paranoid, you can manage CRDs separately with a dedicated Application that syncs first:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd-crds
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
spec:
  source:
    repoURL: https://github.com/argoproj/argo-cd
    path: manifests/crds
    targetRevision: v2.13.0
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd

Sync wave -1 means CRDs deploy before the main ArgoCD Application

When it goes wrong

I’ve had exactly one issue: a bad config that made ArgoCD crash loop. It couldn’t sync because it couldn’t start. Classic deadlock

The fix: kubectl apply the previous working version manually. Once ArgoCD is healthy, it syncs back to git (which you’ve fixed by then)

This is why you want replicas: 2 for the controller. If one pod crashes during upgrade, the other keeps things running

The meta gets deeper

You can go further. ArgoCD managing ArgoCD managing your apps. ArgoCD Image Updater watching for new ArgoCD versions and creating PRs. Renovate bumping the chart version automatically

At some point you’re just watching robots update robots. And that’s the goal. You push code, everything else happens automatically

Should you do this?

Yes. If you’re using ArgoCD for everything else, not using it for ArgoCD itself is inconsistent. You lose the audit trail. You lose the drift detection. You’re back to “I think I ran helm upgrade last month”

The self-management works. ArgoCD handles it gracefully. And there’s something philosophically satisfying about a tool that practices what it preaches

Enjoyed this article? Share it!

Sofiane Djerbi
Sofiane Djerbi

Cloud & Kubernetes Architect, FinOps Expert.

Comments