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

# 概要

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

# 注意

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

# 準備

## IAMロール

1. 下記の情報でIAMロールを作成する。

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | 信頼されたエンティティタイプ | AWSのサービス |  |
    | ユースケース | Lambda |  |
    | 許可ポリシー |  AWSLambdaBasicExecutionRole<br>AWSXRayDaemonWriteAccess<br>AmazonS3FullAccess |  |
    | ロール名 | get-s3-object-lambda-role |  |

## S3

1. 任意のバケット（筆者の場合`miriwo-test`バケット）に`in`というフォルダを作成する。
1. 更に同一バケットに`test`というフォルダを作成する。
1. 両方のバケットが完成すると下記の様になる。

    ![miriwo-test_-_S3_bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/906edeb2-7fc1-da49-6a75-5690ac23c435.png)

1. ちなみに特にバケットは公開状態などにしなくても良い。
1. testフォルダに下記のCSVファイルをtest1.csvとしてアップロードしておく。

    ```test1.csv
    id,name
    1,name_1
    2,name_2
    3,name_3
    4,name_4
    ```

## lambda

1. 下記の情報でlambda関数を作成する。（指定が無いものは設定しない）

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | 関数名 | get-s3-object |  |
    | ランタイム | Node.js 18.x |  |
    | アーキテクチャ | x86_64 |  |
    | 実行ロール | 既存のロールを使用する |  |
    | 既存のロール | get-s3-object-lambda-role |  |

1. 下記のコードをそのままコピペして保存 → 「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.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 |  |
    | イベント共有の設定 | プライベート |  |
    | JSON | 別途記載 |  |

    - イベントJSON

    ```json
    {
      "Records": [
        {
          "s3": {
            "bucket": {
              "name": "miriwo-test"
            },
            "object": {
              "key": "test/test1.csv"
            }
          }
        }
      ]
    }
    ```

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

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5550cc3f-9100-c374-f5fa-745e4fd9ab62.png)


## lambdaトリガー

1. lambda関数のページの「関数の概要」の中の「トリガーを追加」をクリックする。

    ![get-s3-object_-_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/556175c5-4183-0de0-9422-c72716247a25.png)

1. 下記の情報を記載しトリガーを設定する。

    | 項目 | 内容 | 備考 |
    | --- | --- | --- |
    | バケット | miriwo-test | 筆者の場合の設定 |
    | イベントタイプ | すべてのオブジェクト作成イベント |  |
    | プレフィックス - オプション | in/ | フォルダ設定 |
    | サフィックス - オプション | 記入しない | 「csvファイルがアップロードされた時だけ」など指定したい時はこちらで指定 |

# 確認

- 下記の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にファイルアップロード → アップロードイベント起点でlambda関数を実行 → ファイルの内容をログに出力」の流れを実装する事ができた。