【技術検証】S3バケットへのアップロードをトリガーにLambdaを実行する構成を試してみた

## はじめに

いきなり余談ですが、木曜日って1週間の疲れがピークに達するタイミングですよね…。そんな中でもなんとか気合いを入れてアウトプットしていきます！（***※頑張れ自分！！***）

今回は、**S3バケットにファイルがアップロードされたことをトリガーにLambda関数を実行する構成**を構築してみました。

:::note info
AWSのサーバーレス構成の基礎的な組み合わせであり、さまざまな場面で応用可能なパターンです。
:::

内容に不備などがございましたら、お手数ですが優しくご指摘いただけますと幸いです...！

## 書こうと思ったきっかけ

S3バケットにファイルがアップロードされたことをトリガーに、AWS Lambda関数を自動実行する仕組みを今まで技術検証したことがなかったので、手軽に試してみようと思いました。

**こんな感じのよく見る構成です！！**

![Screenshot 2025-06-19 at 22.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/29eadb35-eb37-4129-8f86-3d533cf80e06.png)

引用画像：https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html

ファイル処理や通知など、将来的に応用できそうな構成でもあるため、一度しっかり動かして理解しておきたいと思い、未来の自分に向けて整理してみました！

似たような検証として、S3にホストされた静的ページのURLをLambda関数が返し、そのURLをもとにユーザーにウェブページを表示する、という構成は以前に試したことがありました！

https://qiita.com/free-honda/items/d5c8502cc019b94aa061

## 実際にやってみた

### 1. S3バケットの作成

AWSマネジメントコンソールまたはCLIでバケット（例：`my-upload-bucket-honda`）を作成します。

```bash
aws s3 mb s3://my-upload-bucket-honda
```

**想定通り作成されていることが確認できました！**

![Screenshot 2025-06-19 at 22.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/030b1c14-a8cb-4b98-9a1d-f6ddbff88fc8.png)


### 2. Lambda関数の作成

S3イベントを受け取り、バケット名とファイル名をログに出力するシンプルなPythonコードを用意しました。

```python
import json

def lambda_handler(event, context):
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']
        print(f"S3バケット: {bucket}, アップロードファイル: {key}")
    return {
        'statusCode': 200,
        'body': json.dumps('S3トリガー受信完了')
    }
```

**実際にコードを貼り付けたあとは、下図の赤枠で示した「デプロイ」ボタンをクリックして反映してください！**

![Screenshot 2025-06-19 at 22.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/2ebca11d-bb17-4db6-bc04-2fd3584827ff.png)

IAMロールにはS3アクセス権限とCloudWatchログ出力権限を付与が必要なので、この後解説します。

### IAMロールの変更

今回の構成で必要となる主な権限は以下の通りです：

* **S3アクセス権限**：S3バケットに関する情報を取得（読み取り）する
* **CloudWatch Logs権限**：Lambda関数のログをCloudWatchに出力する

#### 補足：IAMロールの作成手順（マネジメントコンソール）

「ポリシーのアタッチ」画面で以下を選択：

   * `AmazonS3ReadOnlyAccess`
   * `CloudWatchLogsFullAccess`（※実際の運用では最小権限に調整推奨）

作成したロールをLambda関数にアタッチしてください！

![Screenshot 2025-06-19 at 22.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/12fffa81-8511-4919-8b48-bf194e706fd6.png)

:::note alert
本番運用では `CloudWatchLogsFullAccess` や `AmazonS3ReadOnlyAccess` のような広い権限ではなく、以下のように必要なアクションのみに絞ったカスタムポリシーを作成して付与してください！
:::


### 3. S3トリガーの設定

Lambda関数のトリガーとしてS3を設定。イベントタイプは「オブジェクト作成（すべて）」。

CLIからLambda関数への呼び出し権限をS3に付与：

```bash
aws lambda add-permission \
  --function-name my-upload-bucket \
  --principal s3.amazonaws.com \
  --statement-id AllowS3Invoke \
  --action "lambda:InvokeFunction" \
  --source-arn arn:aws:s3:::my-upload-bucket-honda
```

**想定通り設定が反映されていることが確認できました！**

![Screenshot 2025-06-19 at 22.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6318400f-0b2d-4f1b-9a02-bec058a49bae.png)

#### 補足：S3のイベント通知設定について

Lambda関数に対して `aws lambda add-permission` コマンドを実行するだけでは、S3からのイベントで自動的にLambdaが実行されるようにはなりません。

このコマンドはあくまで「S3がLambdaを呼び出すことを許可する」ためのものであり、**S3側にも明示的なイベント通知設定が必要**です。

##### S3 側の設定手順

以下のCLIコマンドを使用して、S3バケットにイベント通知を設定します。

```bash
aws s3api put-bucket-notification-configuration \
  --bucket my-upload-bucket-honda \
  --notification-configuration '{
    "LambdaFunctionConfigurations": [
      {
        "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:xxx:function:my-upload-bucket",
        "Events": ["s3:ObjectCreated:*"]
      }
    ]
  }'
```

この設定により、`my-upload-bucket-honda` バケットにファイルがアップロードされるたびに、指定したLambda関数が実行されるようになります。

**私はこんな感じで、CloudShell 上から実行してみました！**

![Screenshot 2025-06-19 at 22.57.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c103bffa-5614-4c96-8fe4-f593e1c88490.png)

**注意点**

* Lambda関数のARNは、実際の関数に合わせて変更してください。
* バケット名もご自身のものに置き換えてください。

## アップロードして確認してみた

テストファイルをS3にアップロードして、CloudWatch Logsに出力されるか確認していきます。

```bash
echo "test" > test.txt
aws s3 cp test.txt s3://my-upload-bucket-honda/
```

こちらも CloudShell 上で一度実行したうえで、マネジメントコンソールから確認したところ、問題なくアップロードされていることが確認できました！

**実際のマネコン画面**

![Screenshot 2025-06-19 at 22.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d0d40726-3a07-4103-977e-65df8ff5d54c.png)

アップロードと同時にLambdaが自動実行されていることも確認できました！

![Screenshot 2025-06-19 at 23.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/081828fb-b8a8-48d5-b6b8-20ab541a7aba.png)

最後に CloudWatch のログも確認しましたが、想定通りファイル名がログに出力されていました。

![Screenshot 2025-06-19 at 23.03.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/be30c62e-bcc4-4ffa-a7d3-0b19a9324bc7.png)

## まとめ

ここまで読んでいただき、ありがとうございました！S3とLambdaの連携は簡単に実現できることがわかりました（今までやったことなかったのが謎...）。

:::note info
***また、IAMロールの設定や、Lambda関数に対するトリガー許可の設定など、権限まわりの仕組みについても理解を深める良い検証となりました。***
:::

この週末は、CSV処理や画像サムネイル生成など、実用的なLambda処理に発展させてみようと思います...！！