ジェイソンはLambdaを実行できるのか


はじめに

この記事はAWS初心者 Advent Calendar 2019に参加しています。
AWS初学者のため間違い等ありましたらコメントで指摘していただけると大変助かります

ジェイソンって?

ジェイソンとは映画13日の金曜日に登場する殺人鬼の名前です。
JSONではない。
1作目での殺人鬼はジェイソンの母親なので少しタイトルは的外れな感じがありますが気にしないでください。

何がしたいのか

13日の金曜日の時だけLambda関数を実行するルールを作りたい。

ジェイソンはLambdaを実行できる?

結論から言うとできません。
この記事ではその理由とCloudWatchEvents(長いので以後CWE)でのCron式の使い方について解説していこうと思います。

Cron式って?

スケジューリングを行うための式です。
CWEでは6つの項目を設定するCron式を利用します。

cron(分 時間 日 月 曜日 年) 

このように記述します。

実際の例

実際の例をもとにその時使うべきCron式を記述して行きます

その1

例えば毎日正午にお昼ご飯を食べるように通知してくれる関数を作りたいとします。
Lambda側に通知をしてくれるプログラムを記述し、CWEで毎日12時に関数を実行してくれるように設定するとします。
その際のCron式は

Cron(0 3 * * ? *)

のように書きます。
12時なのに3を指定しているのはUTC(協定世界時)で管理されてるからです。

UTC = JST - 9時間 です。

*や?はワイルドカードで特に指定しない場所に記述します。
ここでなぜ*と?を併用しているのかは後ほど説明します。

その2

目覚ましのスヌーズ機能のようにある時間から一定間隔の時間ごとに関数を実行したい場合を考えます。
Cron式では分を指定するところを(開始/間隔)とすることで開始分から間隔分ごとに関数を実行することができます。

24時間5分おきに何かを確認しなければいけない仕事についている人がいるとします。AIに仕事を奪われそうな人No.1ですね。
その人に対して5分間隔で通知を送ってくれるCron式を書くとすると

Cron(0/5 * * * ? *)

と記述します。
すると毎時0分から5分おきにLambda関数を叩いてくれるようになります。

なぜジェイソンはLambdaを実行できないのか

やっと本題に入っていきます。
例の1と2でどちらも曜日の欄にワイルドカード「?」を利用しています。
その理由は日付か曜日のどちらかに「?」を利用しなければならないからです。

公式ドキュメントには次のように書かれています。

You can't specify the Day-of-month and Day-of-week fields in the same cron expression. If you specify a value (or a *) in one of the fields, you must use a ? (question mark) in the other.

片方に値か*を使ったならもう片方には?を使えよ的なことが書いてあります。

つまりこれがジェイソンをLambdaを実行することができないかわいそうな子にしている原因なのです。

Cron(0 0 13 * 6 *) //13日の金曜日になった瞬間に実行されそうな見た目

保存↓

ルール ~ の保存中にエラーが発生しました
詳細: Parameter ScheduleExpression is not valid.。

と出てしまいます。(曜日は日曜日始まりの1-7の数字で指定)

まとめ

もう1つ、Cron式には制限があります。
それは秒までの時間を調整することができないという点です。
なので秒調整の機能はLambda関数側に実装する必要があります。

CWEではこのようにCron式に制限がかかっています。
なかなか日時+曜日で指定することもないとは思いますが、通常設定時にも片方のワイルドカードを?にする必要があるので覚えておくとスムーズに設定を終えることができます。

おわりに

今回は運よく13日の金曜日の欄が開いていたためAdvent Calendar 童貞を卒業 に参加させていただきました、一人でもこの記事が役に立つと感じてくれる方がいてくだされば幸いです