AWS S3のobject createを感知してlambda関数を実行する（EventBridge使用）

## 概要

- S3の特定のバケットにオブジェクトがアップロード（create）されたことを感知して、そのオブジェクトの内容をconsole.logに出力するlambda関数を実行する方法をEventBridgeを使い実装してみる。

## 注意

- 本作業を実施することでAWSにて料金が発生する可能性があります。
- 料金アラートなどを予め設定し高額請求にはくれぐれもご注意ください。
- 筆者は一切の責任を負いかねます。

## 前提

- 下記記事の内容は実施済みのものとして話をすすめる。

https://qiita.com/miriwo/items/4ab4dd1ca49bfa7c9387

- 条件は上記の記事と全く同じで任意のバケット（筆者の場合miriwo-testバケット）にinフォルダを作成し、そこにファイルアップロードイベントが発生した場合lamba関数でキャッチし、ログに出力する。

## 準備

- IAMロール、S3、lambdaはすでに前提の記事で設定済みのものを使用する。

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | IAMロール名 | 	get-s3-object-lambda-role |  |
    | S3 | 任意のバケットを作成しtestフォルダとinフォルダを作成 | testフォルダ内には<br>test1.csvを設置 |
    | lambda関数名 | get-s3-object |  |

### S3

1. S3は追加で作業が必要である。当該のバケットのページに移動する。
1. 「プロパティ」を開く。

    ![miriwo-test_-_S3_bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c1f19bb6-d2c6-9eae-e567-c115029c0768.png)

1. 「Amazon EventBridge」の「編集」をクリックする。

    ![miriwo-test_-_S3_bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/79bb5433-d6a6-8b89-bc27-9f972cf7fb55.png)

1. 「オン」を選択し「変更の保存」をクリックする。

    ![miriwo-test_-_S3_bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3352fc7e-fd4e-5e4f-7c87-233cb1676950.png)

### lambda

1. lambdaの関数部分は一部のみ修正する。下記のコードをそのままコピペして保存 → 「Deploy」をクリックする。

    ```node.js
    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    
    export const handler = async(event) => {
        
        let client = new S3Client();
        let command = new GetObjectCommand({
            Bucket: event.detail.bucket.name,
            Key: event.detail.object.key
            //Bucket: event.Records[0].s3.bucket.name,
            //Key: event.Records[0].s3.object.key
        });
    
        let object = await client.send(command);
        const body = object.Body;
        
        let fileContents = '';
        for await (const chunk of body) {
            fileContents += chunk;
        }
        
        console.log(fileContents);
    
        // TODO implement
        const response = {
            statusCode: 200,
            body: JSON.stringify('Hello from Lambda!'),
        };
        return response;
    };
    ```

1. 「コード」のタブで「Test」をクリックし下記の様に設定して保存する。

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3e2bd9cd-5c0b-2467-e5d2-9b41ad58e207.png)


    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | イベントアクションをテスト | 新しいイベントを作成 |  |
    | イベント名 | test-for-event-bridge |  |
    | イベント共有の設定 | プライベート |  |
    | JSON | 別途記載 |  |

    - イベントJSON

    ```json
    {
      "detail": {
        "bucket": { 
          "name": "miriwo-test"
        },
        "object": {
          "key": "test/test1.csv"
        }
      }
    }
    ```

1. 再び「コード」のタブで「Test」の横の下三角をクリックし、「test-for-event-bridge」を選択してから「Test」クリックしテストを実行する。下記のようにtest1.csvの内容が出力されればコードは問題なく設定できている。

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8535f2f7-3b68-fb70-1bcc-8a0359ca7927.png)

## EventBridge

1. EvnetBridgeのページにアクセスし、サイドメニューから「イベントバス」をクリックする。
1. デフォルトイベントバスの「アクション」をクリックし「検出を開始する」に設定する。
 
    ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/444b5705-1bea-24e3-5dc9-7c0b7009d9e7.png)

1. デフォルトのイベントバスのスキーマの検出が「Started」になっていることを確認する。

    ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/da23c34b-0f1f-3f6d-c8d6-5ce3e2c5b8c2.png)

1. EventBridgeのサイドバーの「ルール」をクリックし、「ルールを作成」をクリックする。

    ![Amazon_EventBridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ab562141-3306-54d2-2ba8-71e6cecc3257.png)

1. 下記の情報を記載しルールを設定する。（指定の無いものは特に設定しない）

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | 名前 | get-s3-object-rule |  |
    | イベントバス | default |  |
    | 選択したイベントバスでルールを有効にする | ON |  |
    | ルールタイプ | イベントパターンを持つルール |  |
    | イベントソース | AWSイベントまたはEventBridgeパートナーイベント |  |
    | 作成のメソッド | カスタムパターン（JSONエディタ） |  |
    | イベントパターン | 別途記載 |  |
    | ターゲットタイプ | AWSのサービス |  |
    | ターゲットを選択 | Lambda関数 |  |
    | 機能 | get-s3-object |  |

    - イベントパターン

        ```json
        {
          "source": ["aws.s3"],
          "detail-type": ["Object Created"],
          "detail": {
            "bucket": {
              "name": ["miriwo-test"]
            },
            "object": {
              "key": [{
                "prefix": "in/"
              }]
            }
          }
        }
        ```

### lambdaトリガー

- すでに登録しているS3イベントトリガーを下記の方法で削除する。
    1. lambda関数のget-s3-objectを開く。
    1. 設定→トリガーとクリックし、S3を選択し「削除」をクリックする。

        ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/46b20de9-ff6e-61fa-7e3d-312420df4a1e.png)

## 確認（前提記事と同じ）

- 下記のtest2.csvファイルを用意する。

    ```test2.csv
    id,name
    1,name_A
    2,name_B
    3,name_C
    4,name_D
    ```

- miriwo-testバケットのinフォルダにtest2.csvをアップロードする。
- lambda関数のget-s3-objectのページまで移動し、「モニタリング」のタブをクリックする。更新ボタンを何回か押下して「Invocations」のグラフに実行状況がプロットされたら、「ログ」をクリックする。

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/128cf20e-c3cd-c0f3-9492-1bed9e96082a.png)

- 最も新しいログストリームのリンクをクリックする。

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/75b4a350-2f0e-5973-cac0-b59e8a6d5d7f.png)

- 下記のようにtest2.csvの内容がCloudWatchのログに出力されていれば実装できている。

    ![CloudWatch_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/26ae3bad-1493-7882-bcde-0fcbec368ee8.png)

- これで「S3にファイルアップロード → アップロードイベントをEventBridgeが感知 → lambda関数を実行 → ファイルの内容をログに出力」の流れを実装する事ができた。