michimani.net

AWS Lambda を毎月 1 日の 00:00 (JST) に実行する

2020-06-04

Amazon EventBridge を使って AWS Lambda を日本時間の毎月 1 日の 00:00 に実行する方法についてです。

目次

※追記 (2021/12/13)

以降 色々と書いてますが、結論としては下記のように cron 式を指定します。

cron(0 15 L * ? *)

Amazon EventBridge の cron 式では、月末を示す L というワイルドカードを使用することができます。なので、上記のように指定することで、日本時間の月初の 00:00 を指定することができます。

The L wildcard in the Day-of-month or Day-of-week fields specifies the last day of the month or week.

Creating an Amazon EventBridge rule that runs on a schedule - Amazon EventBridge

コメントで教えていただきました。ありがとうございました!

概要

今回のポイントは、 「日本時間の毎月 1 日の 00:00」 という部分です。
Amazon EventBridge では、一般的な cron の構文を使ってイベントをスケジュールすることができます。ただし、この cron で指定する日時のタイムゾーンは UTC となっているため、 JST との時差を考慮して指定する必要があります。

JST は +0900 なので、 cron では実際に日本時間で実行したい時間の 9 時間前の日時を指定します。なので、日本時間の毎月 1 日の 00:00 に実行したい場合は、 UNIX 時間の月末の 15:00 を指定することになります。しかし、 cron では 月末 を指定する方法がないため、実行する Lambda 関数側で少し手を加える必要があります。

EventBridge でのスケジュール設定

cron で月末を指定する方法がないとはいえ、月末になり得る日は限られています。なので、 EventBridge では次のような cron 式でスケジュール設定をしておきます。

cron(0 15 28-31 * ? *)

こうすることで、次のようなスケジュールでイベントが発生します。

Sun, 28 Jun 2020 15:00:00 GMT
Mon, 29 Jun 2020 15:00:00 GMT
Tue, 30 Jun 2020 15:00:00 GMT
Tue, 28 Jul 2020 15:00:00 GMT
Wed, 29 Jul 2020 15:00:00 GMT
Thu, 30 Jul 2020 15:00:00 GMT
Fri, 31 Jul 2020 15:00:00 GMT
Fri, 28 Aug 2020 15:00:00 GMT
Sat, 29 Aug 2020 15:00:00 GMT
Sun, 30 Aug 2020 15:00:00 GMT
Mon, 31 Aug 2020 15:00:00 GMT
...

これで各月の月末を網羅することができますが、月末でない日にもイベントが発生してしまいます。なので、実際に月末かどうか (日本時間では 1 日かどうか) を、実行する Lambda 関数側で判定します。

Lambda 関数での日付判定

Lambda 関数内では、実際の処理を行う前に日付の判定を行い、実行時間が日本時間の 1 日でなければそこで処理を終了するようにしています。今回は Go で書いてみます。

まとめ

Amazon EventBridge を使って AWS Lambda を日本時間の毎月 1 日の 00:00 に実行する方法についてでした。 毎日、毎週や 1 日の 09:00 以降の月次であれば cron で解決しますが、毎月 1 日の 09:00 までの実行には Lambda 側で判定が必要になります。


comments powered by Disqus