What is it, naokirin?

AWS Step Functions と Amazon EventBridge で、定時バッチを実行してみる

最近、定時バッチ実行をサーバーレスに移したいと思いながら、そこまで実行できていないので、AWS Step FunctionsとAmazon EventBridgeを用いて、定時バッチ実行を試してみました。

AWS Step Functionsとは

AWS Step Functionsは、AWSが提供するワークフローサービスです。

220以上のAWSサービスやLambdaの呼び出しなどを組み合わせて、複雑なワークフローを記述、実行できます。

aws.amazon.com

また、視覚的なインターフェースもあるため、ドラッグ&ドロップでワークフローを構築することもでき、導入しやすくなっています。

https://docs.aws.amazon.com/images/step-functions/latest/dg/images/wfs_tutorial_result_01.png

引用元:Tutorial: Learn to use the AWS Step Functions Workflow Studio - AWS Step Functions

Amazon EventBridgeとは

Amazon EventBridgeは、AWSが提供するイベント駆動によるアプリケーション同士の接続をしやすくするサービスです。

aws.amazon.com

今回はこのうち、簡単にcronなどのスケジューリングされたイベントによるアプリケーションの実行のための、Amazon EventBridge Schedulerを利用します。

Serverless Task Scheduler - Amazon EventBridge Scheduler – Amazon Web Services

今回作成する定時バッチ

今回はお試しということで、以下のような仕様の定時バッチをつくります。

  • 毎日10時に、特定のS3のバケットのオブジェクト数をメール通知する
  • ただし、土日祝日は通知しない

AWS Systems Manager Change Calendarで、土日祝日を登録しておく

Step Functionsなどからは少しズレますが、ビジネス上、「土日祝日は実行したくない」「毎月第3営業日に実行したい」などの、単純な日付判定では難しいバッチ実行があるかと思います。

こうしたやや複雑な条件の場合には、自前でカレンダー情報を作成するなどして対応するかと思います。

AWSでは、そうしたカレンダー情報をサービスで活用できるように、AWS Systems Manager Change Calendar というサービスが提供されています。

GoogleカレンダーなどからiCal形式などで出力することで、直接カレンダー登録できます。

若干今回の趣旨から外れるので、カレンダーの登録の詳細については、こちらを参考にしてもらえればと思います。

dev.classmethod.jp

AWS Step Functionsを設定する

それでは、まずはStep Functionsを設定していきます。

AWSコンソールから、Step Functions > ステートマシンの作成 を選択します。

初回はチュートリアルが始まるので、そちらは一旦終了して、新規のワークフロー作成を開始します。

今回は、Workflow Studioを利用して作成します。タイプは「標準」にします。

進むと、Workflow Studioが表示されます。

今回はすでに設定したものを表示していますが、最初はステップは何も登録されていないため、必要なステップを左側のパネルから中央のビジュアルエディタにドラッグ&ドロップし、各ステップの詳細設定を右側のパネルで行います。

Change Calendarを読み込む

まずは、Change Calendarから平日かどうかを取得できるようにします。

左側のパネルから、GetCalendarState を検索して追加します。

設定から、APIパラメータを以下にします。 Holiday は作成済みの土日祝日に予定が入っているカレンダーです。

{
  "CalendarNames": [
    "Holiday"
  ]
}

平日のみ実行されるようにする

次に、Choiceを追加します。

Choiceの設定のルールに以下を追加します。

前のステップのGetCalendarStateから出力されたJSONデータが入力されているので、JsonPathで $.State で、カレンダーの予定が空いているかを取得します。空いている場合、土日祝日の登録がないので、平日であることがわかります。

S3のオブジェクト数を取得する

S3の特定のバケットのオブジェクト数が取りたいので、ListObjectsV2 を選択して追加します。

APIパラメータで、バケット名を指定します。

このままだと、このステップでの出力が、バケット内のすべてのオブジェクト情報のリストになり、不要な情報が多いため、必要な情報に絞って出力するようにします。

出力の「ResultSelector を使用して結果を変換」を選択します。その設定に以下を設定します。

{
  "KeyCount.$": "$.KeyCount",
  "MaxCount.$": "$.MaxKeys"
}

これにより、オブジェクト数とAPIでの取得上限数が指定されます。

ListObjectsV2では、最大1000オブジェクトが上限のため、オブジェクト数としてカウントが取得できるのも、1000が上限になります。そのため、最大の取得上限数も載せておくことで、APIの上限以上にオブジェクトができていることがわからないという状況を避けるために、あえてAPIの取得上限数も載せるようにしました。

SNSでメール通知する

最後にSNSを利用して、メール通知します。

SNS側の設定は省略しますが、APIパラメータでSNSのトピックのARNを設定すれば、SNSに通知されて、SNSからメール送信ができます。

特に追加設定をしない場合、入力内容がそのままメール本文に記載されます。

Amazon EventBridge で定時実行を設定する

定時実行を設定します。

EventBridgeから、「EventBridge Schedule」を選択して作成します。

スケジュールのパターンは、以下とします。
土日は、カレンダー登録があれば、Step Functionsでも通知から除外されますが、cronの簡単な設定をするだけで不要にStep Functionsを実行せずに済むので、ここで除外しておきます。

ターゲットの詳細で、AWS Step FunctionsのStartExecutionを選択し、作成したステートマシンを選択して設定します。

これで、月〜金の10時にStep Functionsのステートマシンが実行されるようになります。

実行を確認する

Step Functionsのステートマシンが実行されると、ステートマシンの詳細画面で実行状況などが確認できます。

最後に今回の実行結果として、メールが通知されることが確認できました。

まとめ

AWSAPIの出力結果をドキュメントを読みながら確認できれば、AWS Step FunctionsとAmazon EventBridgeで比較的簡単に定時バッチを作成することができました。

今回はシンプルでしたが、複雑なワークフローなどは、失敗時にどうするかや、無限ループにならないように注意をする必要があります。

特に失敗時は、途中から実行することがStep Functionsの仕様上できないため、注意が必要そうでした。

一方で、複雑かつ途中から実行などが必要な場合でも、LambdaとDynamoDBなどを組み合わせて、実行状況などを記録するなどして、途中で失敗しても途中までの処理をスキップして実行といったことも可能かと思うので、不可能ではないかと思います。

あと、今回はWorkflow Studioを利用しましたが、きちんと管理していくためにCDKなどを利用することも検討が必要になるかと思います。ビジュアルエディタの活用ができなくなるため、トレードオフにはなりますが、複雑なものについては手動での変更による危険性もあるため、IaCの活用も検討になるかと思います。

自前でサーバーを建てて管理するなどのコストは避けられるので、活用していきたいですね。