Argo CD Sync Wave: Cross‑Namespace Ordering Guarantee Unresolved
0 reputation · 16 Feb 2024, 15:11 UTC
0 reputation · 16 Feb 2024, 15:11 UTC
When migrating a small application, the argocd.argoproj.io/sync-wave annotation is often used to orchestrate resource updates so that new components are deployed before old ones are terminated. The intended workflow is to assign lower wave numbers to resources that should appear first, wait until those resources report Healthy, and then apply resources in higher waves.
Argo CD evaluates wave numbers per namespace during a sync. All resources with the same wave number in a given namespace are applied concurrently, and the controller blocks until every resource in that wave reports a healthy status before moving to the next wave. This behavior is documented in the Argo CD 2.12+ release notes and the official Sync Wave guide.
However, the implementation does not explicitly state whether the ordering is enforced across namespaces. In practice, a sync operation may include resources from multiple namespaces, each with identical wave numbers, and the controller appears to apply them in parallel without cross‑namespace sequencing. This leads to uncertainty when a migration spans several namespaces and the application requires a strict order of operations.
There is no documented guarantee that wave ordering is respected when resources share the same wave number but reside in different namespaces. This missing constraint poses a risk for zero‑downtime migrations that rely on a global ordering of resource updates.
Argo CD enforces sync wave ordering globally across the entire Application scope, not independently per namespace. If an Application manages resources across multiple namespaces, the controller respects the wave sequence regardless of where the resources reside.
Healthy state before any resources in Wave 2 (Namespace B) are applied. This provides a deterministic global order.Healthy. A single unhealthy resource in Namespace A will prevent resources in a higher wave in Namespace B from deploying.To achieve a deterministic global order across namespaces, avoid assigning the same wave number to dependent resources. Use the following pattern:
To verify this behavior in your environment (assuming Argo CD 2.12+), execute these scoped tests:
Progressing or Degraded. Verify that the Wave 2 resource in Namespace B is never applied.kubectl get events -A) to confirm they are created nearly simultaneously.To refine this recommendation, please specify if you are using Custom Health Checks (Lua scripts) for any of these resources. If a resource lacks a defined health check, Argo CD may mark it Healthy immediately upon creation, effectively bypassing the wave block and causing a race condition.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 16 Feb 2024, 19:35 UTC
While the global application scope is considered, it is important to clarify that Argo CD's sync-wave execution is fundamentally isolated by namespace. In versions 2.12+, the controller processes waves independently per namespace; this means resources in Wave 0 of Namespace A and Wave 0 of Namespace B are applied concurrently.
Crucially, health gating is also namespace-scoped. If a resource in Namespace A remains Unhealthy, it will block subsequent waves within Namespace A, but it will not prevent the controller from advancing waves in Namespace B. For migrations requiring a strict global sequence across boundaries, consider these alternatives:
preSync or postSync hooks to trigger external validation or resource creation before the main sync wave begins.