2 min read | by Jordi Prats
An exit handler is a template that always executes at the end of a workflow (regardless of whether it completed successfully or returned an error). You can use this run any action, for example: to send notifications after a workflow runs, post the status of the workflow to a webhook, clean up artifacts or run another workflow.
In the following Workflow we are going to make it fail on purpose, and then we are going to use the exit handler to print the status of the workflow:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: exit-handler-
spec:
entrypoint: step1
onExit: exit-handler
templates:
- name: step1
container:
image: alpine:latest
command: [sh, -c]
args: ["echo failed step; exit 1"]
- name: exit-handler
container:
image: alpine:latest
command: [sh, -c]
# {{workflow.status}} can be: Succeeded, Failed or Error
args: ["echo Exit status: {{workflow.status}}"]
If we run this workflow, we can see how it is going to fail:
$ kubectl create -f exithandler.yaml ; kubectl get workflow -w
workflow.argoproj.io/exit-handler-zx78p created
NAME STATUS AGE MESSAGE
exit-handler-zx78p Running 0s
exit-handler-zx78p Running 10s
exit-handler-zx78p Failed 20s Error (exit code 1)
The exit handler is being executed at the end of the workflow in a different container:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
exit-handler-zx78p 0/2 Error 0 42s
exit-handler-zx78p-exit-handler-3923311637 0/2 Completed 0 32s
We can get the logs of the step and the exit handler as usual:
$ kubectl logs exit-handler-zx78p
time="2024-10-28T04:22:48.156Z" level=info msg="capturing logs" argo=true
failed step
time="2024-10-28T04:22:49.157Z" level=info msg="sub-process exited" argo=true error="<nil>"
Error: exit status 1
$ kubectl logs exit-handler-zx78p-exit-handler-3923311637
time="2024-10-28T04:22:58.064Z" level=info msg="capturing logs" argo=true
time="2024-10-28T04:22:59.065Z" level=info msg="sub-process exited" argo=true error="<nil>"
The exit handler is executed in a different container, so it doesn't have access to the workflow logs. However, it can access the workflow status using the {{workflow.status}}
template variable.
Posted on 1/11/2024