Allow a default sync wave per resource kind via argocd-cm
Summary
Within a sync phase and wave, resources are ordered by kind. Every built-in kind in kindOrder gets a negative value, and any kind absent from the table falls through to Go's zero value - so custom resources are applied after every built-in kind. That default is deliberate and matches Helm, but it cannot be overridden anywhere except per object.
I'd like to propose resource.customizations.syncWave.<group_kind> in argocd-cm, applied only to objects that carry no sync wave of their own.
The problem
A webhook served by a cert-manager certificate. One chart, one wave:
| Kind | kindOrder |
|---|---|
Service |
-13 |
Deployment |
-8 |
Certificate (CR) |
0 |
Issuer (CR) |
0 |
The Deployment mounts the TLS secret cert-manager writes, so the pod is created first and fails with MountVolume.SetUp failed ... secret "webhook-cert" not found. Issuer lands after the Certificate that references it, because equal kindOrder falls back to a name comparison.
Annotating both manifests fixes it, and that's the documented answer. It doesn't scale: we run a platform catalogue of ~140 charts, and for third-party charts we'd have to fork or post-process them. A chart author can't know that a consumer installs through Argo CD, and an operator has no way to state the policy centrally.
The same question recurs in #11883, #9112, #6413 — always answered with "use sync waves", which is exactly the part that doesn't scale.
Proposal
resource.customizations.syncWave.cert-manager.io_Issuer: "-3"
resource.customizations.syncWave.cert-manager.io_Certificate: "-2"Resolution: annotation or Helm hook weight → exact key → wildcard key → wave 0. Consistent with the five customization types that already exist.
Proof of concept
Branch: https://github.com/CharlieR-o-o-t/argo-cd/tree/feat/default-sync-wave-per-resource-kind
- syncwaves.Explicit() — tells an object asking for wave 0 from one never given a wave
- sync.WithDefaultSyncWaves() — a SyncOpt shaped like WithHealthOverride, taking a GroupKind lookup so the engine stays free of Argo CD settings types
- reuses the existing syncTask.waveOverride, applied before prune waves are computed so prune ordering stays the mirror of creation ordering
- ResourceOverride.SyncWave is a string so generated deepcopy is unaffected and "unset" differs from "0"
Happy to push it into PR if that's ok.
Source: argoproj/argo-cd