ArgoWrorkflowsで失敗したJobをSlackBot経由で通知する

公開:2021/01/12
更新:2021/01/13
3 min読了の目安(約3400字TECH技術記事

公式ドキュメントで簡単に紹介されているが、exit handlerを使ってWorkflowが失敗した時にSlackに通知する手順を紹介する。

exit hadler

WorkflowのStatus(Succeeded, Failed, Error)によって特定のStepを実行できる。
今回は、Workflowが失敗した時のみSlack通知用のStepを実行するように設定する

Slack通知を行うWorkflowTemplateの用意

Slack通知はいろんなWorkflowで使われるので、WorkflowTemplateとして用意する。

Slackへの通知はslack-cliのDockerイメージを利用した。(DockerhubのLimitに引っかかるのでPullした後にECRなどのレジストリーにおいた方が良い)

WorkflowTemplateは以下のようにしました。
Secretのargo-slack-token.tokenにはSlack Botのトークンが入ります。

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
spec:
  templates:
  - inputs:
      parameters:
      - name: channel
        value: {SLACK_CHANNEL}
      - name: color
        value: danger
      - name: status
      - name: title
      - name: env
        value: {ENV}
      - name: url
        value: https://{URL}/workflows
      - name: workflow-id
      - name: slack-secret
        value: argo-slack-token
    name: failed-notification-to-slack
    script:
      command:
      - sh
      env:
      - name: SLACK_CLI_TOKEN
        valueFrom:
          secretKeyRef:
            key: token
            name: {BOT_TOKENの入ったSecret}
      image: 512k/slack-cli:latest
      imagePullPolicy: IfNotPresent
      source: |
        slack-cli chat send --channel="{{inputs.parameters.channel}}" --color "{{inputs.parameters.color}}" --fields '{"title": "id", "value": "{{inputs.parameters.workflow-id}}", "short": true }, {"title": "status", "value": "{{inputs.parameters.status}}", "short": true }, {"title": "env", "value": "{{inputs.parameters.env}}", "short": true }, {"title": "url", "value": "{{inputs.parameters.url}}/{{inputs.parameters.env}}/{{inputs.parameters.workflow-id}}", "short": true }' --text '*{{inputs.parameters.title}}*'

ここでslack-cliの--fieldsに好きなSlackの好きなメッセージを入れることで、Slackへの通知の仕方をカスタムできます。
parametersのurlの部分に、UIのURLを入れることで失敗したWorkflowのURLを付け加えることができます。

このサンプルの場合、以下のようなメッセージがSlackに通知されます。

実際の利用方法

最後にこのWorkflowTemplateを使う側ですが、以下のようにWorkflowTempalteをTempalteRefで参照して利用するだけです。
またonExitの部分に先ほどのTemplateを参照して作ったStepを指定することで、Workflowの終了時にそのStepを実行させることができます。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: test-exit-handlers-
spec:
  entrypoint: intentional-fail
  onExit: exit-handler ## ここでexit-handlerを指定
  serviceAccountName: workflow-runner
  templates:
  - name: intentional-fail # 必ず失敗するstep
    container:
      image: alpine:latest
      command: [sh, -c]
      args: ["echo intentional failure; exit 1"]

  - name: exit-handler
    steps:
    - - name: slack-notification
        when: "{{workflow.status}} != Succeeded"
        templateRef: ## ここでWorkflowTemplateを指定
          name: slack   
          template: failed-notification-to-slack
        arguments:
          parameters:
          - name: title
            value: "{{workflow.name}}が失敗しました"
          - name: status
            value: "{{workflow.status}}"
          - name: workflow-id
            value: "{{workflow.name}}"

Helm等で管理している場合は毎回Workflowに入れるのが面倒かもしれないが、DefaultWorkflowに指定することで毎回入れなくてもWorkflowを追加することができる