EventBridgeルールで設定したいスケジュールがCronで表現出来ない時は、複数のルールを組み合わせることを考えよう

2021.11.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、Amazon EventBridgeルールで設定したいスケジュールがCronで表現出来ない時は、複数のルールを組み合わせることを考えようという話です。

「7:30〜24:00の間だけ1分毎に実行する」スケジュールがCronで表現できなかった

「毎日、日本時間7:30〜24:00の間は1分毎に定期実行し、それ以外の時間は実行しない」というスケジュールをLambda関数に設定する要件がありました。

このような場合はAmazon EventBridgeでルールを作成します。ルールのイベント送信スケジュールの設定方法には「Rate式」と「Cron式」の2種類がありますが、今回のように一定期間実行する期間と実行しない期間があるスケジュールの場合はCron式を使用することになります。

Cron式のフォーマットは以下のようになります。

cron(Minutes Hours Day-of-month Month Day-of-week Year)

しかしこのCron式を使用して今回のスケジュールを表現することができませんでした。制約となるのは「7:30〜24:00」の部分で、「分」と「時間」という異なる時間単位を使用した期間であるためCron式で対応しきれませんでした。

下記のようにHoursパラメータを22.5-14で指定(UTCなので9時間ずれます)すると、ScheduleExpressionエラーとなってしまいます。

cron(* 22.5-14 ? * * *) //エラーとなる

複数のルールを組み合わせたらできた

そこで複数のEventBridgeルールを組み合わせることにより、所要のスケジュールによる実行を実現することができました。

//7:30〜7:59
cron(30-59 22 ? * * *)

//8:00〜23:59
cron(* 23-14 ? * * *)

マネジメントコンソールでトリガーのサンプルを見ると、ちゃんと要件通りのスケジュールとなっているようです。

曜日が絡むとさらに複雑になる

先ほど少し触れましたがEventBridgeルールのCron表現はUTCで行う必要があるため、JSTより9時間遅れであることを考慮する必要があります。この考慮はHours以外のパラメータでももちろん必要です。

例えば「月曜〜土曜日の7:30〜24:00(日本時間)の間は1分毎に定期実行し、それ以外の時間は実行しない」という前述のものに更に曜日の条件が加わったスケジュールの場合は、以下の3つのCronのイベントを使用する必要があります。

//月曜から土曜の7:30〜7:59
cron(30-59 22 ? * SUN-FRI *)

//月曜から土曜の08:00〜08:59
cron(* 23 ? * SUN-FRI *)

//月曜から土曜の09:00〜23:59
cron(* 0-14 ? * MON-SAT *)

Lambda関数を挟んで制御することも考える

ここまで複雑なパターンのクーロンを作る方法を考えてきましたが、例えば時間帯によって実行間隔を変えたり、祝日を考慮するなど、さらに実行条件が複雑になるパターンももちろんあります。しかしそうなるとクーロンの設定だけでは対処が難しいか、出来るにしても複雑になり過ぎるため、その場合はルールと実行したい処理の間にLambda関数を設けて、その関数内で実行のタイミングを制御する処理とする方法も選択肢に入れましょう。

イメージとしては、下記のようにEventBridgeのルールのターゲットにLambda関数を指定して、クーロンによる実行をフィルターし、条件に合えばその先の実際の処理を実行するような構成です。

参考

以上