Lambdaの無限ループが一部対策されたみたいなので試してみた！

# はじめに
**Lambda**皆さん大好きですよね？？？

僕も月並みには好きです。そんなLambdaですが、定期的に**無限ループ**による高額請求の記事やスライドを見かけます。
そんな問題に終止符を打つ１歩目のアップデートがありました。
>意図しないループの影響を軽減するために、Lambda は特定の種類の再帰ループを発生直後に検出できます。Lambda は再帰ループを検出すると、関数の呼び出しを停止し、通知します。

https://docs.aws.amazon.com/lambda/latest/dg/invocation-recursion.html

現在は、**Amazon SNS・Amazon SQS**による無限ループの検知をサポートしているとのことです。



## 試してみる
以下の記事に記載のサンプルコードを参考に試してみる。
SAMを使用して、Lambda + SQSを使用した無限ループが行える環境を作成する。
https://github.com/aws-samples/aws-lambda-recursion-detection-sample


### 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/81b61b2d-1cfc-0223-560a-88497c0dd245.png)

### デプロイ
環境変数へデプロイ先のリージョン名を設定する。今回は東京に設定。
```
$ export REGION=ap-northeast-1
```

サンプルコードをcloneしてくる
```
$ git clone https://github.com/aws-samples/aws-lambda-recursion-detection-sample.git
$ cd aws-lambda-recursion-detection-sample
```

ビルド＆デプロイを実行
```
$ sam build --use-container
$ sam deploy --guided --region $REGION
```
#### 注意点
**※参考ページに記載の`--use-container`の部分のハイフンに違うものが混じってるので間違えると以下のエラーが表示される。**
```
$ sam build –-use-container
–-use-container not found. Possible options in your template: ['LambdaFunction']

Build Failed
Error: Unable to find a function or layer with name '–-use-container'
```


## 無限ループを実行
SAMで作成されたStackからSQSのURLを抽出する。
```
$ SOURCE_SQS_URL=$(aws cloudformation describe-stacks --region $REGION --stack-name lambda-recursion --query 'Stacks[0].Outputs[?OutputKey==`SourceSQSqueueURL`].OutputValue' --output text)
```

作成したSQSにメッセージをパブリッシュして無限ループを開始する。
```
$ aws sqs send-message --queue-url $SOURCE_SQS_URL --message-body '{"orderId":"111","productName":"Bolt","orderStatus":"Submitted"}' --region $REGION
```

## ちゃんと止まっているか確認
Lambdaのメトリクスを確認してみるとちゃんと16回で止まっていますね！！
この16回というのはAWS内で定義された無限ループを検知してから停止されるまでの実行数のようです。
>同じトリガーイベントによって関数が 16 回を超えて呼び出される場合、Lambda はそのイベントに対する次の関数呼び出しを停止し、再帰ループを中断します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/758cde5f-3507-4c09-4ab8-9f093155e6ec.png)
そして、16回の無限ループを検知するごとに`RecursiveInvocationsDropped`というメトリックがカウントされるようです。
>単一のリクエストチェーンで関数が 16 回以上呼び出されたために Lambda が停止した関数呼び出しの数を記録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/0c5c9fd0-e9cd-3a24-8e2a-cea10cdeffac.png)

### 通知
無限ループが発生した際に以下の以下の3つの通知があり、そのうち`AWS Health Dashboardh`と`電子メールアラート`については最大３時間のラグが発生するとのことです。

- AWS Health Dashboardhへの通知
- 電子メールアラート
    - AWSアカウントの関数ごとに24時間ごとに最大1通のメールを送信。
    - 通知先のメールアドレスはアカウントに紐づくものとなります。
- Amazon CloudWatch メトリクス
    - `RecursiveInvocationsDropped`

#### メール
約3時間後に受信してました。
```サンプル.txt
Hello,

AWS Lambda has detected that one or more Lambda functions in your AWS Account: 098619850637 are being invoked in a recursive loop with other AWS resources. To prevent unexpected charges from being billed to your AWS account, Lambda has stopped the recursive invocations for the following functions:

arn:aws:lambda:ap-northeast-1:12345678910:function:loop-detection-LambdaFunction-jeNhA1HBNqX8 at time Tue Jul 11 11:22:00 UTC 2023

What do I need to do?

Please review your functions and their trigger configurations to identify any unintentional recursive patterns. To prevent further recursive invocations of your function, follow the instructions in the AWS Lambda Developer Guide [1].

If your design intentionally uses recursive patterns, please contact AWS Support [2] to turn off recursive loop prevention for Lambda.

[1] https://docs.aws.amazon.com/lambda/latest/dg/invocation-recursion.html
[2] https://aws.amazon.com/support
```
#### AWS Health Dashboardh
Other notificationsにメールと同じ文面で通知がきている。
>Lambda runaway termination notification

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/69587d7b-7762-5a68-5eeb-da8774940cad.png)


## まとめ
- 個人的にはかなりアツいアップデートだと感じています。
    - 現在はAmazon SNS・Amazon SQSのみのサポートなのでS3などもサポートしてくれるとありがたいですね！
- CloudWatch メトリクスをトリガーに任意のメールアドレスにも通知できそうなので、試してみたいです。
- 勿論これまで通り無限ループの注意は必要ですが、Lambdaを記述する方々の心理的余裕が少しでも生まれそうで開発者的には嬉しい機能かと思いました。

## 参考ページ
- https://docs.aws.amazon.com/lambda/latest/dg/invocation-recursion.html
- https://aws.amazon.com/jp/blogs/compute/detecting-and-stopping-recursive-loops-in-aws-lambda-functions/
- https://github.com/aws-samples/aws-lambda-recursion-detection-sample