はじめに
昨年11月末にAWSから「Lambda Destinations(Lambda非同期呼び出しの宛先指定)」機能が発表されました。
そしてこの機能について、3月中旬に「Serverless Frameworkが正式サポート」したと公式ブログで発表がありました。
そこで、早速この機能をServerless Frameworkで使ってみました。
前提:「Lambda Destinations(Lambda非同期呼び出しの宛先指定)」って?
概要としては、以下の機能になります。
- Lambda実行結果に従って、次のアクション(=実行リソース)を指定できる。
- 正常終了(Success)/異常終了(Failure)で個別に指定可能
- 指定可能なアクション(=実行リソース)は、以下の通り
- Simple Queue Service(SQS)
- Simple Notification Service(SNS)
- Lambda
- Event Bridge
- 非同期実行のLambda(=各種イベントで実行されるLambda)のみ設定可能
※API Gateway経由Lambdaでも、非同期で実施することは可能です。
【参考】
- https://aws.amazon.com/jp/blogs/compute/introducing-aws-lambda-destinations/
- https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-async.html
実践:Serverless Frameworkで実装してみる
※前提として、前掲のServerless Framework公式ブログに記載の通り、Serverless Frameworkのバージョンを1.66.0以上にしてください。
serverless.ymlの「functions」セクションで、以下のようなLambda関数を定義します。 (今回はSuccess/Failure共に、アクションはLambda関数にしています)
functions: Challange: handler: challange.index events: # API Gatewayは通常は同期実行(Lambda Destination対象外)だけど、テスト用に実装 - http: path: /challange method: get ## 実際はこんな感じで、何かのイベントで実行するように実装する(元リソースの定義は省略) - schedule: rate(10 minutes) # 「onSuccess」/「onFailure」に成功時/失敗時の定義名を記載する destinations: onSuccess: Success onFailure: Failure # 成功時のリソースの定義を記載(Lambdaの場合はハンドラを定義) Success: handler: succeeded.index # 失敗時のリソースの定義を記載(Lambdaの場合はハンドラを定義) Failure: handler: failed.index
定義としては、以上です。
なお上記関数ですが、下記の内容となります。(シンプルすぎるので内容は省略)
- challange.index:onSuccess検証時は何もせずにreturnするだけ、onFailure検証時は何かErrorをthrowする。
- succeeded.index/failed.index:console.log()でログを1行書き出すだけ
invokeでテスト実行する
上記serverless.ymlをデプロイしたら、実際にテストをしてみます。
※デプロイ成功していれば、「Challange」Lambda内に下記の通り「非同期呼び出し」ソースが二つ追加されます。
デプロイを確認したら「invoke」コマンドでテストを行います。
ここで気を付けるのは、「invoke」コマンドを非同期(=イベント)で呼び出すには「--type」オプションに「Event」オプションを指定しないといけない点です。
これを忘れると「--type=RequestResponse」(=同期呼び出し)として実行されるため、Lambda Destinationは正常に機能しません。
(堀家さん、ありがとうございます。)
# test.jsonはchallange.index実行時のevent引数の内容をそのまま指定 # 「--type Event」を忘れないこと! > slss invoke --function Challange --path test.json --type Event
正常に実行されると、特に何も表示されずにコマンドが終了しますので、CloudWatch Logを確認します。
CloudWatch Logを確認すると、成功時/エラー発生時共に正しくアクション先Lambdaが実施され、ログが書き出されていることが分かります。
- 上が成功時、下がエラー発生時
- 画像は1つにまとめてますが、実際はどちらもchallange.index、及びsucceeded.index(またはfailed.index)のログです。
- エラー発生時にchallange.indexのログが3つあるのは、2回リトライ処理を実施しているためです。
なお、Serverless Framework公式の下記動画でも、Serverless FrameworkによるLambda Destinationsの実装が詳しく紹介されています。 www.youtube.com
まとめ
以上がServerless FrameworkでLambda Destinationsを実装する方法です。
Lambda Destinationsですが、成功時/失敗時の処理を個別に切り出せるので、下記のようなメリットがあると思います。
- 成功時&エラー時の処理を、同一ソースに書かなくてよい。
- 上記により、ソースの可視性&保守性の向上につながる
- リトライ処理を考慮した成功時&エラー時の処理を実装できる
こういう便利な機能は、どんどん活用していきたいですね。
告知
4/24(金)にオンラインで開催される「Infra Study Meetup #1 ~Infrastructure as Code~」に「Infrastructure as Codeを導入して良かった点」という内容でオンライン登壇させて頂きますので、よろしくお願いいたします。(てか4/18(土)時点で、参加者2000人超えそうな勢いなんだけど...)
それでは、今回はこの辺で。