はじめに

以前、AWS Step Functionsを利用した基本的な処理についてご紹介しましたが、今回はさらに進んだ利用法に焦点を当てます。
具体的には、正常系通知および異常系通知をSNS(Simple Notification Service)を使用して行う方法と、通知内容に実行ID(ExecutionId)を含める方法について解説します。

イメージ

まずLambdaを処理するように定義し、成功した場合の通知タスク、失敗した場合の通知タスクを定義します。

正常系通知および異常系通知の設定

AWS Step Functionsを使用していると、処理が正常に完了した場合やエラーが発生した場合に通知を受け取りたいと思うことがあります。
SNSはこのような場面で強力なツールとなります。以下は通知の設定手順です。

1. 正常系通知の設定
処理が正常に終了した場合に通知を受け取りたい場合、例えばSnsSuccessNotifyといったステップを追加します。
このステップでは、Lambda関数が成功した旨のメッセージをSNSに送信します。
送信されたメッセージにはExecutionIdも含め、詳細な情報を把握できます。

    "SnsSuccessNotify": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "Message": {
          "ExecutionId.$": "$$.Execution.Id",
          "Message": "Lambda関数の処理を完了しました"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:[アカウントID]:[SNSトピック名]"
      },
      "Next": "SuccessProcess"

1. 異常系通知の設定
もし処理中にエラーが発生した場合、通知を行うようにCatchステートを利用します。
そして、例えばSnsFailNotifyといったステップを追加します。
このステップでは、エラーメッセージを含んだ通知をSNSに送信します。
同様に、ExecutionIdも含めてエラーのトラッキングを行います。

    "lambda-test-1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:[アカウントID]:function:lambda-test-1",
      "InputPath": "$",
      "ResultPath": "$.SearchResult",
      "OutputPath": "$",
      "Next": "SnsSuccessNotify",
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "SnsFailNotify"
        }
      ]
    },
    "SnsFailNotify": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "Message": {
          "ExecutionId.$": "$$.Execution.Id",
          "Message": "Lambda関数の処理が失敗しました。"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:[アカウントID]:[SNSトピック名]"
      },
      "Next": "SuccessProcess"

通知内容に実行IDを含める方法

通知を受け取るだけでなく、通知内容に実行IDを含めることで、特定の実行の詳細情報を素早く把握することができます。
以下はその手順です。

1. 通知メッセージの設定
通知メッセージのパラメータに、"ExecutionId.$": "$$.Execution.Id"を追加します。
これにより、通知メッセージには実行IDが含まれ、通知を受けた際にすぐに関連する実行を特定できます。

各種設定内容

1. ステートマシン

{
  "Comment": "sample",
  "StartAt": "lambda-test-1",
  "States": {
    "lambda-test-1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:[アカウントID]:function:lambda-test-1",
      "InputPath": "$",
      "ResultPath": "$.SearchResult",
      "OutputPath": "$",
      "Next": "SnsSuccessNotify",
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "SnsFailNotify"
        }
      ]
    },
    "SnsSuccessNotify": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "Message": {
          "ExecutionId.$": "$$.Execution.Id",
          "Message": "Lambda関数の処理を完了しました"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:[アカウントID]:[SNSトピック名]"
      },
      "Next": "SuccessProcess"
    },
    "SnsFailNotify": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "Message": {
          "ExecutionId.$": "$$.Execution.Id",
          "Message": "Lambda関数の処理が失敗しました。"
        },
        "TopicArn": "arn:aws:sns:ap-northeast-1:[アカウントID]:[SNSトピック名]"
      },
      "Next": "SuccessProcess"
    },
    "SuccessProcess": {
      "Type": "Succeed"
    }
  }
}

2. lambda-test-1

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

正常系の実行

ステートマシンの実行を開始よりデフォルトのまま実行をします。

処理が成功しました。

成功メール通知に実行IDが付与されています。

これでたくさん実行されててもどのジョブの通知が来たのかわかりますね!

異常系の実行

ステートマシンのIAMロールからlambda-test-1へのアクセスポリシーを削除します。

ステートマシンの実行を開始よりデフォルトのまま実行をします。
処理が失敗しました。

失敗メール通知に実行IDが付与されています。

今回の構成でいうとステートマシンの定義的には完了となりますのでここでは成功と表示されてしまいます。

まとめ

正常系通知と異常系通知をSNSを活用して設定することで、システムの動作監視が格段に容易になります。
また、通知内容に実行IDを含めることで、特定の実行に素早くアクセスし、トラブルシューティングを効率化できます。今回ご紹介した手法をAWS Step Functionsの運用の際に参考にしていただければ幸いです。

最後まで閲覧いただきありがとうございました。