How do Helm hooks control the lifecycle of install, upgrade, and rollback operations, and How do you use hook-delete-policy and hook weights to orchestrate ordered multi-step operations?
Quick Answer
Helm hooks are resources annotated with helm.sh/hook that run at specific lifecycle points like pre-install, post-upgrade, or pre-delete. Hook weights control execution order within the same hook phase, and hook-delete-policy determines whether hook resources are cleaned up after success, failure, or before the next hook runs. Architects use these to orchestrate database migrations, health checks, and notification steps in a deterministic order.
Detailed Answer
Think of a theater production. Before the curtain rises (pre-install), stagehands check lighting and sound. After the final act (post-install), the crew verifies props are stored. If a show is cancelled mid-run, specific cleanup happens (pre-delete). Hook weights are like a call sheet that says the lighting check happens at 6 PM (weight -5), sound check at 6:30 PM (weight 0), and dress rehearsal at 7 PM (weight 5). Helm hooks give Kubernetes deployments the same structured choreography.
Helm hooks are standard Kubernetes resources — Jobs, Pods, ConfigMaps, or any resource — annotated with helm.sh/hook to indicate when they should be created. The available hook points are pre-install, post-install, pre-upgrade, post-upgrade, pre-rollback, post-rollback, pre-delete, post-delete, and test. When Helm reaches a hook point during a release operation, it pauses the normal resource application, creates the hook resources, waits for them to complete (for Jobs and Pods), and then continues. If a hook fails, the entire operation fails.
Internally, Helm processes hooks within each phase by sorting on the helm.sh/hook-weight annotation, which accepts any integer value. Lower weights run first, so a database migration Job with weight -10 runs before a cache warmup Job with weight 0, which runs before a notification Job with weight 10. Resources with the same weight are sorted by resource kind and then name. The helm.sh/hook-delete-policy annotation controls cleanup: hook-succeeded deletes the resource after success, hook-failed deletes after failure, and before-hook-creation deletes any existing hook resource before creating a new one. Without a delete policy, hook resources accumulate across upgrades, which causes naming conflicts and resource clutter.
At production scale, hooks are essential for zero-downtime upgrades of stateful services. A pre-upgrade hook running a database schema migration Job ensures the new schema exists before new Pods start. A post-upgrade hook can run integration smoke tests against the new version. The atomic flag (--atomic) interacts with hooks: if a post-upgrade hook fails and --atomic is set, Helm automatically rolls back the entire release including any pre-upgrade changes, which can be dangerous if the pre-upgrade hook made irreversible changes like a destructive migration. Architects should design hook operations to be idempotent and reversible when used with --atomic.
The non-obvious gotcha is that hook resources are not managed as part of the release. They do not appear in helm get manifest, are not tracked for drift detection, and are not automatically upgraded when the chart version changes. If a hook Job uses an image tag that changes between releases but the Job manifest is identical, Helm may skip recreating it because the resource already exists — unless before-hook-creation is set as the delete policy. Architects should always set hook-delete-policy: before-hook-creation for Jobs to ensure fresh execution on every release operation.