この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、坂巻です。
先日、Step Functionsにアップデートがあり、ステートマシンの実行ステータスが変化したときにCloudWatchイベントが発行できるようになりました。
[アップデート]Step Functionsの実行ステータスが変化したときにCloudWatchイベントが発行できるようになりました!
今回はこちらの機能を利用し、Slackにステートマシンの実行ステータスを通知してみたいと思います。
目次
- 構成図
- Slack Webhook設定
- Lambda関数作成
- ステートマシン作成
- CloudWatchイベントルール作成
- 動作確認
構成
ステートマシンのステータスが変化した際に、CloudWatchイベントを発行し、CloudWatchイベントルールにてLambda関数を起動させます。
Slack Webhook設定
Slackワークスペースに「Incoming WebHooks」アプリを追加します。以下、URLにアクセスします。
https://ワークスペース名.slack.com/apps
上記URLのワークスペース名は適宜読み替えてください。
検索より「Incoming WebHooks」を入力し、結果に表示された「Incoming WebHooks」をクリックします。
「設定を追加」クリックします。
通知先のチャンネルを指定し「Incoming Webhook インテグレーションの追加」をクリックします。
WebHookのURLが表示されますので、このURLを控えておきます。(後ほどLambda関数で使用します。)
Lambda関数作成
CloudWatchイベントルールで起動させるLambda関数と、ステートマシンから起動させるLambda関数を作成します。
LambdaToSlack
CloudWatchイベントルールで起動させるLambda関数を作成します。
ここでは、メンション先(SlackメンバーID)を入力イベントで受けとるようにしました。ステータスがSucceeded
以外の場合、output
フィールドはNULL
になりますので、ステータスを判定してSucceeded
の場合は、ステートマシン(Lambda)が生成した値を通知し、Succeeded
以外の場合は、ステートマシンの実行ARNをメッセージとします。
先程控えた、SlackのWebhook URLは、環境変数に設定します。
Lambda関数のコードは以下となります。
import json
import os
from urllib.request import Request, urlopen
def lambda_handler(event, context):
#環境変数よりWebHook URL取得
hook_url = os.environ['HOOK_URL']
#ステートマシンのステータス取得
sf_status = event['detail']['status']
#ステートマシン実行ARN取得
sf_exec_arn = event['detail']['executionArn']
#inputイベントは文字列型のため辞書型に変換
input_event = json.loads(event['detail']['input'])
#SlackメンバーID取得
slack_user_id = input_event['SlackUserId']
#ステータス判定
if sf_status == "SUCCEEDED":
#outputイベントは文字列型のため辞書型に変換
output_event = json.loads(event['detail']['output'])
#メッセージを取得(ステートマシンにて実行されるLambdaで生成)
sf_result = output_event['result']
#メッセージ整形
message = "status : " + sf_status + "\n" + "result : " + sf_result
else:
#メッセージ整形
message = "status : " + sf_status + "\n" + "result : " + sf_exec_arn
#SlackメンバーIDをメンション形式に整形
mention = "<@" + slack_user_id + ">"
slack_message = {
'text': mention + "\n" + message,
# メンション有効
'link_names': 1
}
req = Request(
hook_url,
json.dumps(slack_message).encode('utf-8'),
)
#リクエスト
response = urlopen(req)
response.read()
Function1
ステートマシンから起動させるLambda関数を作成します。実行時に渡すイベントで、戻り値を変えています。
def lambda_handler(event, context):
flg = event['Function1']
if flg == "Success":
ret_msg = "Function1 Success"
else:
ret_msg = "Function1 Fail"
return ret_msg
Function2
ステートマシンから起動させるLambda関数を作成します。実行時に渡すイベントで、戻り値を変えています。
def lambda_handler(event, context):
flg = event['Function2']
if flg == "Success":
ret_msg = "Function2 Success"
else:
ret_msg = "Function2 Fail"
return ret_msg
ステートマシン作成
Lambda関数を実行するステートマシンを作成しました。呼び出されたLambda関数は戻り値を返すようにしているので、Choice
にて戻り値を判定し、ステートを分岐させています。また、ResultPath
を使用して入力イベントの一部を置き換えています。
ステートマシンの定義は以下となります。
{
"StartAt": "Functions1",
"States": {
"Functions1": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:Function1",
"ResultPath": "$.result",
"Next": "Functions1 Success ?"
},
"Functions1 Success ?": {
"Type": "Choice",
"Choices": [{
"Variable": "$.result",
"StringEquals": "Function1 Success",
"Next": "Functions2"
}],
"Default": "EndFail"
},
"Functions2": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:Function2",
"ResultPath": "$.result",
"Next": "Functions2 Success ?"
},
"Functions2 Success ?": {
"Type": "Choice",
"Choices": [{
"Variable": "$.result",
"StringEquals": "Function2 Success",
"Next": "EndSuccess"
}],
"Default": "EndFail"
},
"EndFail": {
"Type": "Fail"
},
"EndSuccess": {
"Type": "Succeed"
}
}
}
CloudWatchイベントルール作成
ステートマシンが発行するCloudWatchイベントにて、Lambda関数を起動させるルールを作成します。
先程作成したステートマシンのARNを指定し、ここではSUCCEEDED
と、FAILED
ステータスを設定しました。ターゲットには先程作成したLambda関数「LambdaToSlack」を指定します。
動作確認
成功時
SUCCEEDED
ステータスの動作を確認します。以下のイベントを渡しステートマシンを実行します。
{
"Function1": "Success",
"Function2": "Success",
"SlackUserId": "UA7TVTSD6"
}
「EndSuccess」ステートが実行され、ステータスが「成功」になりました。
指定したSlackユーザに、Lambda関数(Functions2)が生成した値「Function2 Success」が通知されました。
失敗時
Function1エラー
FAILED
ステータスの動作を確認します。以下のイベントを渡しステートマシンを実行します。
{
"Function1": "Fail",
"Function2": "Success",
"SlackUserId": "UA7TVTSD6"
}
「EndFail」ステートが実行され、ステータスが「失敗」になりました。
指定したSlackユーザに、ステートマシンの実行ARNが通知されました。
Function2エラー
FAILED
ステータスの動作を確認します。以下のイベントを渡しステートマシンを実行します。
{
"Function1": "Success",
"Function2": "Fail",
"SlackUserId": "UA7TVTSD6"
}
「EndFail」ステートが実行され、ステータスが「失敗」になりました。
指定したSlackユーザに、ステートマシンの実行ARNが通知されました。
さいごに
これまでステートマシン内で生成した値を通知しようとなると、つくりこみが必要でしたが、今回のアップデートで簡単に通知できるようになりましたね!!