LoginSignup
0
0

More than 1 year has passed since last update.

【AWS】Step Functionsの実行結果をSlackへ通知する

Last updated at Posted at 2023-04-29

StepFunctionsを用いてBIツール用のAthena集計テーブルを1日1回更新していますが、実行結果をSlackで知りたいと思いました。

以下のような形で機能を作ってみたので、構成までの手順を書こうと思います。
structure.png

設定

Slack

まずはincoming-webhookアプリを設定します。
設定方法はこちらのページを見ていただければと思います。

通知対象としたい「チャンネル名」「チャンネルID」と「Webhook URL」をメモします。

Incoming Webhook _ Slack App ディレクトリ.png

無題.png

SNS

AWSコンソールで「Simple Notification Service」を開きます
トピック→トピックの作成でトピックを作ります。

  • タイプ
    • スタンダート
  • 名前
    • お好きな名前

として、トピックを作成します。

image.png

Lambda

AWSコンソールで「Lambda」を開きます
関数→関数の作成から関数を作ります

  • 関数名
    • お好きな名前
  • ランタイム
    • Python 3.10

image.png

「関数の概要」からトリガーを追加します。
SNSトピックはSNSで作成したものを選択します。

トリガーの追加 - Lambda.png

lambda_function.pyには以下のコードを記載します。
Webhook URLとSlackチャンネルはSlack設定のものを用いてください。

lambda_functions.py
import urllib3
import json

http = urllib3.PoolManager()


def lambda_handler(event, context):
    url = "SlackのWebHookURL"
    rec = event["Records"][0]["Sns"]["Message"]
    if type(rec) == str:
        rec = json.loads(rec)
    message_blocks = [
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": f':information_source: *<https://{rec["region"]}.console.aws.amazon.com/states/home?region={rec["region"]}#/v2/executions/details/{rec["detail"]["executionArn"]}| {rec["detail-type"]} | {rec["region"]} | Account: {rec["account"]}>*',
            },
        },
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": f'*State Machine Arn*\n\
```\n\
{rec["detail"]["stateMachineArn"]}\n\
```\n',
            },
        },
    ]

    msg = {
        "channel": "#Slackチャンネル名",
        "username" : "AWS-StepFunctions-Result",
        "blocks" : message_blocks,
    }

    encoded_msg = json.dumps(msg).encode("utf-8")
    resp = http.request("POST", url, body=encoded_msg)
    print(
        {
            "message": event["Records"][0]["Sns"]["Message"],
            "status_code": resp.status,
            "response": resp.data,
        }
    )

ここのコードですが、後述する入力ステートメントの設定によってeventの中身を変えることができます。

Lambda関数のテストを行う場合は、それ用のイベントを設定する必要があるので、以下のjsonを用いてください。

{
  "Records": [
    {
      "EventSource": "aws:sns",
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:us-east-1:{{{accountId}}}:ExampleTopic",
      "Sns": {
        "Type": "Notification",
        "MessageId": "MessageId",
        "TopicArn": "arn:aws:sns:ap-northeast-1:{{{accountId}}}:ExampleTopic",
        "Subject": "example subject",
        "Message": {
          "version": "0",
          "id": "id",
          "detail": {
            "executionArn": "arn:aws:states:ap-northeast-1:{{{accountId}}}:execution:TestEvent",
            "stateMachineArn": "arn:aws:states:ap-northeast-1:{{{accountId}}}:stateMachine:TestEvent",
            "name": "xxxxxxxxxx",
            "status": "SUCCEEDED",
            "startDate": 1682167551859,
            "stopDate": 1682167551935,
            "input": "{\n    \"Comment\": \"Insert your JSON here\"\n}",
            "output": "{\"source\":[\"aws.states\"],\"detail-type\":[\"Step Functions Execution Status Change\"],\"detail\":{\"status\":[\"SUCCEEDED\",\"FAILED\"]}}",
            "inputDetails": {
              "included": true
            },
            "outputDetails": {
              "included": true
            },
            "error": null,
            "cause": null
          },
          "detail-type": "[SUCCEEDED] Step Functions Execution Status Change",
          "source": "aws.states",
          "account": "{{{accountId}}}",
          "time": "2023-04-22T12:45:52Z",
          "region": "ap-northeast-1",
          "resources": [
            "https://ap-northeast-1.console.aws.amazon.com/states/home?region=ap-northeast-1#/executions/details/arn:aws:states:ap-northeast-1:{{{accountId}}}:execution:TestEvent",
            "{\n    \"Comment\": \"Insert your JSON here\"\n}"
          ]
        },
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "SignatureVersion": "1",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "UnsubscribeUrl": "EXAMPLE",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        }
      }
    }
  ]
}

この状態でテストを実行すると、以下のような投稿がSlackに流れると思います。

image.png

StepFunctions

StepFunctionsは実行結果を知りたい対象なので、簡単にHello Worldのステートマシンを使います。
実際は、定期実行するステートマシンを対象としてください。
AWSコンソールで「Step Functions」を開きます。
ステートマシン→ステートマシンの作成→コードでワークフローを記述

で、定義を以下として「次へ」を押します。

HelloWorld定義
{
  "Comment": "A Hello World example of the Amazon States Language using Pass states",
  "StartAt": "Hello",
  "States": {
    "Hello": {
      "Type": "Pass",
      "Result": "Hello",
      "Next": "World"
    },
    "World": {
      "Type": "Pass",
      "Result": {
        "source": [
          "aws.states"
        ],
        "detail-type": [
          "Step Functions Execution Status Change"
        ],
        "detail": {
          "status": [
            "SUCCEEDED",
            "FAILED"
          ]
        }
      },
      "End": true
    }
  }
}

image.png

EventBridge

AWSコンソールで「Amazon EventBridge」を開きます。

ルール→ルールを作成

  • 名前
    • お好きな名前
  • ルールタイプ
    • イベントパターンを持つルール
  • イベントソース
    • AWSイベントまたはEventBridgeパートナーイベント
  • 作成のメソッド
    • パターンフォームを使用する

イベントパターンは以下のように設定します。
Step FunctionsのSUCCEEDED,FAILEDをキャッチするようにします。
そして、対象のステートマシンArnを記載します。

SnapCrab_NoName_2023-4-29_7-49-29_No-00.png

イベントパターン
{
  "source": ["aws.states"],
  "detail-type": ["Step Functions Execution Status Change"],
  "detail": {
    "status": ["SUCCEEDED", "FAILED"],
    "stateMachineArn": ["arn:aws:states:ap-northeast-1:xxxxxxxxx:ステートマシンの名前"]
  }
}
  • ターゲット
    • ターゲットタイプを以下のように設定します。トピックはSNS設定で作成したものを選択します。

image.png

  • 追加設定
    • ターゲット入力を設定
      • 入力トランスフォーマー

ターゲット入力トランスフォーマーには以下のコードを設定します。

ターゲット入力トランスフォーマー
{
    "detail-executionArn": "$.detail.executionArn",
    "source": "$.source",
    "detail-name": "$.detail.name",
    "version": "$.version",
    "detail-input": "$.detail.input",
    "detail-type": "$.detail-type",
    "detail": "$.detail",
    "id": "$.id",
    "time": "$.time",
    "region": "$.region",
    "account": "$.account",
    "detail-status": "$.detail.status"
}

テンプレートには以下のコードを設定します。

テンプレート
{
    "version": <version>,
    "id": <id>,
    "detail":<detail>,
    "detail-type": "[<detail-status>] <detail-type>",
    "source": <source>,
    "account": <account>,
    "time": <time>,
    "region": <region>,
    "resources": [
        "https://<region>.console.aws.amazon.com/states/home?region=<region>#/executions/details/<detail-executionArn>",<detail-input>
    ]
}

実行

StepFunctionsで作成したステートマシンを実行します!
(本来はEventBridge Schedulerで定期実行します)

SnapCrab_NoName_2023-4-29_21-13-38_No-00.png

以下のようにSlackに通知が送られます

SnapCrab_NoName_2023-4-29_21-15-23_No-00.png

失敗を試す

HelloWorldのStepFunctionsの定義を以下のように書きかえてわざと失敗させ、失敗の通知についてもSlackへ送られるのかチェックします。

{
  "Comment": "A Hello World example of the Amazon States Language using Fail states",
  "StartAt": "Hello",
  "States": {
    "Hello": {
      "Type": "Pass",
      "Result": "Hello",
      "Next": "FailState"
    },
    "FailState": {
      "Type": "Fail",
      "Error": "Failure",
      "Cause": "This state machine is designed to fail"
    }
  }
}

SnapCrab_NoName_2023-4-29_21-21-18_No-00.png

失敗の通知も受け取ることが出来ました!ヤッタゾ

参考

何か不足点やアドバイス等いただけますと嬉しいです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0