AWS Lambda は、Amazon SQS、Amazon DynamoDB、Amazon Kinesis をイベントソースとするイベントフィルタリングをサポートしました

# はじめに

https://aws.amazon.com/jp/about-aws/whats-new/2021/11/aws-lambda-event-filtering-amazon-sqs-dynamodb-kinesis-sources/

> AWS Lambda は、イベントソースとして SQS、DynamoDB、Kinesis のコンテンツフィルタリングオプションを提供するようになりました。イベントパターンのコンテンツフィルタリングでは、お客様が指定したフィルタリング条件の下で、SQS、DynamoDB、Kinesis からのみ Lambda 関数がトリガーされるような複雑なルールを書くことができます。これにより、お客様の Lambda 関数へのトラフィックを減らし、コードを簡素化し、全体的なコストを削減することができます。
>
> お客様は、SQS、DynamoDB、Kinesis をトリガーとする Lambda 関数のためにイベントソースマッピングを作成または更新する際に、最大 5 つのフィルター条件を指定することができます。フィルターの組み合わせは、デフォルトでは OR 論理で行われます。つまり、定義されたフィルタリング条件のいずれかに合致するイベント/ペイロードは Lambda 関数のトリガーに渡され、フィルタリング条件のどれにも合致しないイベント/ペイロードはドロップされます。この機能により、利用可能なイベントのサブセットのみを使用するマイクロサービスの関数呼び出しを減らし、対象となる Lambda 関数やダウンストリームアプリケーションがフィルタリングを実行する必要がなくなります。
>  
> 
> コンテンツフィルタリングは、AWS Lambda が利用できるすべての商用リージョンで利用可能です。この機能を使用するために、AWS Lambda の標準料金以上の追加費用はかかりません。
> 
> この機能の詳細については、イベントフィルタリングのための AWS Lambda ドキュメントをご覧ください。

の記事の更新内容を確認してみました。

# どんな更新

Lambdaのトリガに設定したSQS、DynamoDB、Kinesisに対しフィルタリング条件を設定することで、無駄なLambda呼び出しを減らすことが出来るようになった。

# これまでは

- 呼び出されたLambda側でフィルタリングしてあげる必要があった。 :no_good: 

# なにがうれしいか

- Lambdaを呼び出す前にフィルタリングすることで、Lambda側のフィルタリングロジックがなくなる :blush:

- Lambdaの呼び出し回数が減ってお財布にやさしい :smile:

# 料金は

Lambdaにかかる通常料金以外に追加費用はなし :moneybag:

# やってみる

![sqstoLambda.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/e4890622-a905-f2ff-1605-61a537a0a274.png)

- Labmda側フィルタリング条件
    - ProductName要素が存在する場合、Lambdaが発火するように指定
- SQSメッセージ
    - ProductName要素が存在するメッセージを送信する

適当なSQSを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/c0760d7e-b400-802e-1c7d-3ac6babcec4a.png)

適当なLambda[^1]を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/95d33889-9169-a233-8a95-35294e45e465.png)

トリガーを追加して......
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/3af583b1-828e-58df-f1e3-59d5d1ce8fc0.png)

追加の設定を開き、フィルタリング条件を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/e64cd626-69ac-57d8-17b1-1ecb1b6552bc.png)

フィルタリング条件については

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

を参考に。

今回はSQSから送信するメッセージのJSON構造が

```json:SQSから送信するメッセージ
{
	"DataName": {
		"messageAttributes": {},
		"md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
		"eventSource": "aws:sqs",
		"eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
		"ProductName": "product name aruyo"
	}
}
```

であるため、フィルタリング条件を

```json:Lambdaフィルタリング条件
{
    "body": {
        "DataName": {
           "ProductName": [ { "exists": true } ]
        }
    }
}
```

のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/bd0d6f7d-5109-3d34-e90d-2dbcf63483d1.png)

追加すると、以下のようにフィルタリング条件が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/d8a7e499-cb80-84cf-02c3-3f4fda406499.png)

これで準備は完了です。

では、メッセージを送信してみましょう。

メッセージ本文にメッセージjsonを指定してメッセージを送信すると......

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/0bdda4c8-7b12-1aa0-7fed-08daa40091ac.png)

Lambdaが動作したことが確認できました。[^2]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/80b4bc90-48ce-36fe-50b0-fa7e302b839c.png)

# まとめ

LambdaのトリガにSQS、DynamoDB、Kinesisを利用する＆特定の条件に一致した場合のみ動作させたいという場合、こちらの機能を思い出しましょう。

# さいごに

Lambdaのフィルタリング条件にデータプロパティを指定するとき、イベントソース(SQS, DynamoDB, Kinesis)によってデーターキーを変える必要があります。

```json:SQSの場合bodyになる
{
    "body": {
        "Data1": [ pattern ]
    }
}
```

```json:dynamodbの場合dynamodb
{
    "dynamodb": {
        "Data1": [ pattern ]
    }
}
```

```json:Kinesisの場合data
{
    "data": {
        "Data1": [ pattern ]
    }
}
```

この形式で設定しないとうまく動かないので注意しましょう。[^3]



# 参考

https://dev.classmethod.jp/articles/event-source-mapping-support-filter-expression/

[^1]: ログに受け取ったjsonデータを吐くだけのLamda
[^2]: CloudWatch logsのログで動作確認
[^3]: ハマりました