S3 バケットに csv ファイルがアップロードされたら Lambda を動かしてみる

2024.01.22

こんにちは!よしななです。 今回は、S3 Bucket と Lambda を組み合わせて、S3 バケット にファイルがアップロードされたときに Lambda を返すやり方を試してみたいと思います。

目次

  • 構成
  • 事前準備
    • サインイン
    • S3 バケットの作成
    • IAM ロールの作成
  • 検証環境の作成
    • Lambda の作成
    • テスト
  • 実行
    • CloudWatch Logs での確認
    • リソースの削除
  • まとめ

構成

今回試してみるサービスの構成図は以下になります。

やりたいこととしては、以下の通りです。
1. S3 バケットに test.csv をアップロード
2. S3 イベント通知が Lambda を呼び出す
3. 結果が CloudWatch Logs に出力される

事前準備

AWS にサインインする

AWS コンソールからサインインが必要です。
以下の公式ドキュメントを参考に、サインインを行います。
参考リンク(公式ドキュメント)

S3 バケットの作成

まず、csv ファイルをアップロードするための S3 バケットを作成します。
ホーム画面上部 → 検索コンソールから S3 を検索 → バケットを作成 をクリックします。
バケット作成画面に遷移するので、ここから S3 バケットを作成します。

設定項目

AWS リージョン:アジアパシフィック (東京) ap-northeast-1 を選択します。
バケット名:任意の名前を入力します。
※S3 バケットのリージョンと Lambda のリージョンは一緒にしてください。リージョンが別だと S3 イベント通知作成時に作成した Lambda 関数の選択ができません。
その他の設定はデフォルトの状態にします。

バケット作成をクリックすると、以下の画面の通りアジアパシフィック (東京) ap-northeast-1 に S3 バケットが作成されました。

csv ファイルのアップロード

続いて、作成した S3 バケットに 今回の検証のトリガーとなる csv ファイルのアップロードを行います。
作成したバケットを選択 → アップロードをクリックします。

以下の画面に遷移するので、ファイルのアップロードをクリックするとエクスプローラーが開くので、該当のファイルを選択してアップロードします。こちらでファイルのアップロードが完了となります。

IAM ポリシーの作成

Lambda に付与するための IAM ポリシーを作成します。
ホーム画面上部 → 検索コンソールから IAM を検索 → ポリシー → ポリシーの作成 をクリックします。
ポリシーの作成画面に遷移するので、ここから IAM ポリシーを作成します。
JSON タブから IAM ポリシーを編集し、終わったら次へをクリックします。

今回許可するリソース

  • S3 バケット
    • GetObject
  • CLoudWatch Logs
    • CreateLogGroup
    • CreateLogStream
    • PutLogEvents

IAMポリシー.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:ap-northeast-1:{アカウントID}:*"
        },
        {
            "Effect": "Allow",
            "Action": [
            "logs:CreateLogStream",
            "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-northeast-1:{アカウントID}:log-group:/aws/lambda/{作成したLambda名}:*"
        }
    ]
}

ポリシーの名前を入力し、完了をクリックします。こちらでポリシーの作成は完了となります。

ロールの付与

Lambda に付与するための IAM ロールを作成します。
ホーム画面上部 → 検索コンソールから IAM を検索 → ロール → ロールの作成 をクリックします。
信頼されたエンティティを選択画面に遷移するので、Lambda を入力します。

許可ポリシー画面に遷移するので、先ほど作成したロールを検索から探してクリックします。

名前、確認、および作成画面に遷移するので、ロール名を入力します。

終わったら作成をクリックします。
こちらで IAM 上の作業はすべて完了となります。

検証環境の作成

Lambda の作成

処理の核となる Lambda を作成します。
ホーム画面上部 → 検索コンソールから Lambda を検索 → 関数 → 関数の作成 をクリック

関数の作成画面に遷移するので、関数を作成していきます。

設定項目

  • 関数名
    • 任意の名前を付けます
  • ランタイム
    • Python 3.10
  • アクセス権限 → デフォルトの実行ロール
    • 既存のロールを使用を選択
      • 先ほど作成したロール名を入力

ここまで終わったら作成をクリックすると、以下の画面に遷移します。

こちらの部分にコードを書いていきます。完成したら Deploy をクリックするとコードの保存が完了となります。

test_lambda.py

import json
import urllib.parse
import boto3

print('Loading function')

s3 = boto3.client('s3')

def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        print("CONTENT TYPE: " + response['ContentType'])
    return response['ContentType']
        except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

S3 イベント通知の設定

Lambda の作成が完了したら、S3 イベント通知の設定を行います。
こちらで S3 → Lambda 関数間の連携が可能になります。
作成した S3 バケット → プロパティ → イベント通知 → イベント通知の作成 をクリックします。

以下の画面に遷移するので、イベント名などの設定を行います。

設定項目

  • イベント名:任意のイベント名を入力
  • イベントタイプ:S3 バケットでどのアクションが発生したら後続の処理を動かすかを設定
    • 今回は PUT を指定
  • 送信先:Lambda を指定
  • Lambda 関数:作成した Lambda 関数を指定



こちらで設定が完了になるので、変更の保存をクリックします。
こちらで実行準備は完了となります。次項で作成した Lambda 関数のテストをしていきます。

テスト

Lambda 関数の作成と、S3 イベント通知の設定が完了したらテストを実施します。
テストタブをクリックすると以下の画面に遷移します。

テストのテンプレートが複数用意されているので、テンプレートを S3 Put に変更します。
変更すると、自動で JSON テストが作成されます。こちらを編集し、テストコードを完成させます。

編集ポイント

  • "awsRegion":S3 バケット / Lambda を作成したリージョンを指定する
  • "bucket"
    • "name":作成したバケット名を入力
    • "arn":"arn:aws:s3:::{作成したバケット名}" を入力
  • "object"
    • "key":アップロードする csv 名を入力。今回は test.csv を入力

test.json

{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "ap-northeast-1",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "{バケット名}",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::{バケット名}"
        },
        "object": {
          "key": "{CSV名}",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]

テストコードが書き終わったら、テストボタンをクリックします。
次項でテスト結果の確認をしていきます。

テスト結果 - CloudWatch Logs の確認

成功すると以下の画面が表示されます。

ログをクリックすると CLoudwatch Logs でログの詳細を確認できます。

無事テストが成功したので本番実行をしてみます。

実行

作成した S3 バケットにファイルをアップロード

それでは、S3 バケットに該当のファイルを入れてLambda を動かしてみます。
作成したS3 バケットを開き、test.csv をアップロードします。

こちらで問題なく Lambda が動いていれば CloudWatch Logs に結果が出力されるはずです。

CloudWatch Logs の確認

CloudWatch Logs を確認してみます。

成功していれば、S3 バケットに test.csv をアップロードした時間の結果が出力されているはずです。
今回は問題なく出力できました!
以上で、S3 バケットに csv ファイルがアップロードされたら Lambda を動かしてみる、は完了となります。

リソースの削除

今回作成した S3,Lambda,IAM は削除しておきます。

まとめ

S3 イベント通知の設定には、PUT 以外の設定ができたり、送信先を SQS などに指定できるようなので、自動化がはかどりそうだなと思いました。
S3 イベント通知の設定の代わりに、Eventbridge の設定が使えるようなので、次回はそちらの検証を行ってみようと思います!
ここまで見ていただきありがとうございました!