StepFunctionsを用いてBIツール用のAthena集計テーブルを1日1回更新していますが、実行結果をSlackで知りたいと思いました。
以下のような形で機能を作ってみたので、構成までの手順を書こうと思います。
設定
Slack
まずはincoming-webhookアプリを設定します。
設定方法はこちらのページを見ていただければと思います。
通知対象としたい「チャンネル名」「チャンネルID」と「Webhook URL」をメモします。
SNS
AWSコンソールで「Simple Notification Service」を開きます
トピック→トピックの作成でトピックを作ります。
- タイプ
- スタンダート
- 名前
- お好きな名前
として、トピックを作成します。
Lambda
AWSコンソールで「Lambda」を開きます
関数→関数の作成から関数を作ります
- 関数名
- お好きな名前
- ランタイム
- Python 3.10
「関数の概要」からトリガーを追加します。
SNSトピックはSNSで作成したものを選択します。
lambda_function.py
には以下のコードを記載します。
Webhook URLとSlackチャンネルはSlack設定のものを用いてください。
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に流れると思います。
StepFunctions
StepFunctionsは実行結果を知りたい対象なので、簡単にHello Worldのステートマシンを使います。
実際は、定期実行するステートマシンを対象としてください。
AWSコンソールで「Step Functions」を開きます。
ステートマシン→ステートマシンの作成→コードでワークフローを記述
で、定義を以下として「次へ」を押します。
{
"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
}
}
}
EventBridge
AWSコンソールで「Amazon EventBridge」を開きます。
ルール→ルールを作成
- 名前
- お好きな名前
- ルールタイプ
- イベントパターンを持つルール
- イベントソース
- AWSイベントまたはEventBridgeパートナーイベント
- 作成のメソッド
- パターンフォームを使用する
イベントパターンは以下のように設定します。
Step FunctionsのSUCCEEDED,FAILED
をキャッチするようにします。
そして、対象のステートマシンArnを記載します。
{
"source": ["aws.states"],
"detail-type": ["Step Functions Execution Status Change"],
"detail": {
"status": ["SUCCEEDED", "FAILED"],
"stateMachineArn": ["arn:aws:states:ap-northeast-1:xxxxxxxxx:ステートマシンの名前"]
}
}
- ターゲット
- ターゲットタイプを以下のように設定します。トピックはSNS設定で作成したものを選択します。
- 追加設定
- ターゲット入力を設定
- 入力トランスフォーマー
- ターゲット入力を設定
ターゲット入力トランスフォーマーには以下のコードを設定します。
{
"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で定期実行します)
以下のようにSlackに通知が送られます
失敗を試す
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"
}
}
}
失敗の通知も受け取ることが出来ました!ヤッタゾ
参考
何か不足点やアドバイス等いただけますと嬉しいです!