Argo CD Resource Hooks: Synchronization Phases and Lifecycle Management
Argo CD resource hooks let you attach custom Kubernetes resources—typically Jobs, Pods, or Argo Workflows—to specific points in the application sync lifecycle using the argocd.argoproj.io/hook annotation.
In the argoproj/argo-cd project, resource hooks enable complex deployment patterns like database migrations, smoke tests, and cleanup operations by executing arbitrary resources at predetermined phases of the synchronization process. These hooks integrate with Argo CD's sync waves and deletion policies to provide fine-grained control over application lifecycle events.
What Are Argo CD Resource Hooks?
Argo CD resource hooks are Kubernetes resources annotated with argocd.argoproj.io/hook that execute during specific phases of the application synchronization lifecycle. Unlike standard application resources, hooks run independently and can succeed or fail without necessarily blocking the main deployment—though failure behavior depends on the specific phase.
The annotation accepts six possible values:
- PreSync – Runs before the main synchronization begins
- Sync – Runs during the main synchronization phase
- PostSync – Runs after successful completion of the sync
- SyncFail – Runs only when the sync itself fails
- PreDelete – Runs before application resources are deleted
- PostDelete – Runs after application resources are deleted
- Skip – Excludes the resource from hook execution entirely
According to the implementation in gitops-engine/pkg/sync/hook/hook.go, Argo CD parses these annotations to determine resource placement within the synchronization orchestration.
Sync Phases and Execution Order
Argo CD determines hook execution order through a hierarchical sorting mechanism implemented in gitops-engine/pkg/sync/sync_phase.go. The system groups resources first by phase, then applies secondary sorting criteria.
Phase Ordering
Resources execute in strict phase order:
- PreSync – Pre-deployment tasks like schema migrations
- Sync – Main application resources and inline hooks
- PostSync – Post-deployment verification and notifications
- SyncFail – Failure recovery and alerting (only executes if sync fails)
Hooks never run during selective sync operations. If any hook fails during PreSync, Sync, or PostSync phases, the entire synchronization stops immediately.
Wave and Kind Ordering
Within each phase, Argo CD applies the following sorting logic:
- Sync Wave – Resources are ordered by the
argocd.argoproj.io/sync-waveannotation value from lowest to highest (negative waves execute first) - Kind – Namespaces deploy before other resources, followed by custom resource definitions
- Name – Alphabetical order serves as the final tie-breaker
This ordering ensures that dependencies resolve correctly before dependent hooks execute.
Hook Deletion Policies
Resource hooks persist in the cluster unless explicitly removed via the argocd.argoproj.io/hook-delete-policy annotation. The available deletion policies include:
- HookSucceeded – Deletes the hook resource after successful completion
- HookFailed – Deletes the hook resource if it fails
- BeforeHookCreation – Deletes the previous hook resource before creating a new one (default behavior)
The deletion policy implementation ensures that failed hooks remain available for debugging unless explicitly configured otherwise.
Deletion Hooks (PreDelete and PostDelete)
Argo CD provides specialized hook phases for application deletion workflows:
-
PreDelete hooks execute before any application resources are removed and block deletion until they succeed. This enables graceful shutdown sequences, backup operations, or external dependency notifications.
-
PostDelete hooks run after all application resources are deleted. Unlike other phases, a failing PostDelete hook does not recreate the Application; instead, it leaves a
DeletionErrorcondition on the Application resource for manual cleanup.
These hooks are validated in test/e2e/hook_test.go, which contains comprehensive end-to-end tests for all hook phases including deletion behaviors.
Practical Examples
PostSync Notification Hook
Run a Slack notification after successful deployment:
apiVersion: batch/v1
kind: Job
metadata:
generateName: app-slack-notification-
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: slack-notification
image: curlimages/curl
command:
- curl
- -X
- POST
- --data-urlencode
- >-
payload={"channel":"#ops","text":"Argo CD sync succeeded","icon_emoji":":rocket:"}
- https://hooks.slack.com/services/...
restartPolicy: Never
backoffLimit: 2
PreSync Database Migration
Execute database migrations before the main sync using wave -1:
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
argocd.argoproj.io/sync-wave: "-1"
spec:
ttlSecondsAfterFinished: 360
template:
spec:
containers:
- name: psql
image: my-postgres-data:11.5
env:
- name: PGPASSWORD
value: admin
command: ["psql", "-h", "my_postgresql_db", "-U", "postgres", "-f", "preload.sql"]
restartPolicy: Never
backoffLimit: 1
Skipping Helm-Generated Hooks
Exclude Helm-generated hooks that would otherwise block synchronization:
ingress-nginx:
controller:
admissionWebhooks:
annotations:
argocd.argoproj.io/hook: Skip
Implementation in the Argo CD Codebase
The core logic for Argo CD resource hooks resides in several key locations:
gitops-engine/pkg/sync/hook/hook.go– Defines hook type parsing and phase categorization logicgitops-engine/pkg/sync/sync_phase.go– Implements the phase mapping and execution ordering algorithmstest/e2e/hook_test.go– Contains end-to-end tests validating PreSync, Sync, PostSync, SyncFail, PreDelete, and PostDelete behaviorsdocs/user-guide/sync-waves.md– User-facing documentation for hook phases and wave configuration
These files work together to parse annotations, sort resources into execution phases, and manage the lifecycle of hook resources during synchronization operations.
Summary
- Argo CD resource hooks use the
argocd.argoproj.io/hookannotation to execute Jobs, Pods, or Workflows at specific synchronization phases. - Execution follows strict ordering: PreSync → Sync → PostSync → SyncFail, with PreDelete and PostDelete handling application removal.
- Within phases, resources sort by sync-wave (lowest to highest), then Kind, then Name.
- The
argocd.argoproj.io/hook-delete-policyannotation controls cleanup behavior with options forHookSucceeded,HookFailed, andBeforeHookCreation. - PreDelete hooks block application deletion until completion, while PostDelete hooks run asynchronously after resource removal.
Frequently Asked Questions
What happens if a PreSync hook fails?
If a PreSync hook fails, Argo CD stops the entire synchronization process before applying any main application resources. The sync status reports as failed, and the application remains at its previous version until the hook succeeds or is removed.
Can I use resource hooks with selective sync?
No, hooks do not execute during selective sync operations. According to the implementation in gitops-engine/pkg/sync/sync_phase.go, selective sync bypasses the standard phase orchestration to apply only specific resources, excluding hook processing.
How do sync waves interact with hooks?
The argocd.argoproj.io/sync-wave annotation works within hook phases to establish execution order. Resources with lower wave numbers (including negative values) execute before higher numbers. This allows you to chain multiple hooks sequentially, such as running a schema migration at wave -1 and a data validation at wave 0 during the PreSync phase.
What is the difference between Skip and HookSucceeded deletion policies?
Skip is a hook type that prevents Argo CD from treating a resource as a hook entirely, causing it to sync normally with the application. HookSucceeded is a deletion policy that removes the resource only after it completes successfully. Skip changes whether Argo CD recognizes the resource as a hook, while HookSucceeded determines when to clean up recognized hooks.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →