AWSでサーバーレス開発：Docker × ECR × Lambdaで「Hello from Lambda!」を実現してみた

## はじめに
AWSでDockerファイルを使用してコンテナイメージを実行する際には、ECR (Elastic Container Registry) にアップロードされたイメージを利用します。

:::note warn
**この記事では、ECRにアップロードしたイメージをAWS Lambdaで実行し、サーバーレス環境で「***Hello from Lambda!***」を試してみた内容をまとめています。**
:::

今回は、苦戦したポイントも含めて、忘れないように自分用の備忘録として記録しました。

## 前回の続きになります
今回は、ローカル環境でDockerfileを作成し、AWS CLIを使用してDockerイメージをECRにプッシュした内容の続きです。

👉 **Dockerイメージの作成とECRへのプッシュ**

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

Lambda関数を使用するには、IAMロールの作成や権限の設定が必要です。***そのため、AWS CLIを使用してIAMの権限設定を行いました。***

👉 **IAMロールと権限設定について**

https://qiita.com/free-honda/items/488ce653fbffb8bacf3d

これまでの技術検証を踏まえ、今回はECRにアップロードされたイメージをAWS Lambdaで実行し、サーバーレス環境で「***Hello from Lambda!***」を実現する手順をお届けします。

![Screenshot 2025-01-14 at 7.36.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/04454ea8-d2d5-cfe8-2425-f7b8bf8b5622.png)
引用画像：https://blog.denet.co.jp/deployed-to-lambda-in-containerized-form/

今回の構成イメージ図です。

## 書こうと思ったきっかけ
以前からECRとLambdaを活用した技術検証に挑戦したいと思っていたものの、なかなか時間を取ることができませんでした。

:::note info
しかし、今回周辺知識をキャッチアップする中で、「**とりあえず簡易的でも良いから、Hello from Lambda! を実現してみよう**」と思い立ち、技術検証を行いました。
:::

***今回は、つまずいたポイントも多かったため、それらを整理しつつ記事としてまとめることにしました。***

## `x86_64`と`arm64`の違いにめちゃくちゃハマった
普段、Apple Silicon (M1) を搭載したMacBook Proを使用しています。

:::note alert
**この場合、Lambda作成時に、`arm64` を選択する必要がありましたが、デフォルト設定のまま `x86_64` を選択してしまいました。**
:::

**補足**

- **Macのチップが Intel:** `x86_64`
- **Macのチップが Apple Silicon:** 通常は `arm64` （ただし、`x86_64` が必要なら上記の方法で対応可能）

### なぜハマったのか？
実は、連日AWS CLIを使ってさまざまな設定を行っていたこともあり、Lambda関数を以下のコマンドで作成しました。

```bash
aws lambda create-function \
  --function-name my-docker-lambda \
  --package-type Image \
  --code ImageUri=<account_id>.dkr.ecr.<region>.amazonaws.com/my-lambda-repo:latest \
  --role <execution-role-arn>
```

しかし、このコマンドを実行した際、デフォルトのまま `x86_64` が選択されてしまいました。

以下の画像のような状態です。

![Screenshot 2025-01-14 at 7.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/01cea15f-272e-1777-f8b9-2850a0a1c64c.png)

なお、Dockerでイメージをビルドする際、異なるアーキテクチャ向けのイメージを作成することも可能です。

:::note warn
**その場合、明示的にプラットフォームを指定する必要があります。**
:::

今回は、AWS CLIではなく、手動でLambda関数を作成しています（後述します）。

## 前提条件

***以下の項目が事前に設定・完了している必要があります。***

- AWS CLI が設定済み
  - AWS CLI をインストールし、適切に設定されていること。

- Docker がインストール済み
  - Docker がインストールされ、正常に動作する環境が整っていること。

- ECR のリポジトリが作成済み
  - コンテナイメージをアップロードするためのリポジトリが用意されていること。

- 必要な IAM 権限が設定済み
  - Lambda 関数の実行や ECR へのアクセスに必要な IAM ロールと権限が構成されていること。

### Dockerfile

このファイルでは、AWS Lambda の公式 Python ベースイメージを使用し、必要なパッケージやハンドラファイルを設定します。

```Dockerfile
FROM public.ecr.aws/lambda/python:3.9

# 必要なパッケージのインストール（例: requests）
RUN pip install requests

# ハンドラファイルをコピー
COPY app.py ${LAMBDA_TASK_ROOT}

CMD ["app.lambda_handler"]
```

### app.py

Lambdaハンドラを作成します。以下の内容を `app.py` に記述してください。

```app.py
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

このコードは、AWS Lambdaがリクエストを受け取った際に実行される関数を定義しています。

### Dockerイメージをビルド
以下のコマンドを使用して、`Dockerfile` を基にLambda関数で実行可能なコンテナイメージを構築します。

```bash
docker build -t lambda-container .
```

### ECRにイメージをプッシュする方法
ローカルで作成したDockerイメージをAWS CLIを使用してECRにプッシュする手順については、以下の記事で詳しく解説しています。

***ぜひ参考にしてみてください！***

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

**補足**

Lambda関数を使用するためには、IAMロールや権限の設定が必要です。

:::note info
***AWS CLIを使用してIAM周りの権限を付与する方法については、以下の記事を参考にしてください。***
:::

https://qiita.com/free-honda/items/488ce653fbffb8bacf3d

## 実際にLambdaを実行してみた
上記の反省を踏まえ、今回は手動でLambda関数を作成していきます。

**Lambdaの関数作成画面から「コンテナイメージ」を選択し、ECRにアップロード済みのコンテナイメージを指定します。**

![Screenshot 2025-01-14 at 8.07.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/fc9e14ab-2b11-1c74-dc8b-ffc983a1c14b.png)

**ポイント**

- **アーキテクチャ**:
  - 自分の環境に適したもの（例: x86_64 や arm64）を選択してください。

- **実行ロール**:
  - あらかじめ作成しておいたIAMロールを選択します。

![Screenshot 2025-01-14 at 8.09.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/54a20613-3b5e-9307-89b4-62792eb59fb0.png)

Lambda関数をテスト実行するためには、イベント名を指定したファイルを作成する必要があります。

***ここでは「`test`」という名前のイベントファイルを作成しました。***

![Screenshot 2025-01-14 at 8.19.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/38055b83-35d9-9346-a166-2fc6914db4d4.png)

***イベントのJSONデータでは、デフォルトの値をそのまま使用しました。***

**テストの実行と結果**

作成したイベントファイルを使用してLambda関数をテストすると、以下のように実行ログが即座に出力されます。

```実行.log
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}
```

以下のスクリーンショットの通り、実行中のLambda関数が成功ステータスを返し、期待通りの動作を確認できました。

![Screenshot 2025-01-14 at 8.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/cf3f556e-0f6b-158c-5a28-16a5b0c9daf1.png)

## まとめ
最後までお読みいただきありがとうございました。***今回は、過去の技術検証を組み合わせた内容でしたが、無事に最後までやり遂げることができ、ほっとしています。***

途中で苦戦した場面もあり、一時は技術検証自体をお蔵入りにしようかと考えたこともありました。

:::note info
**しかし、最後まであきらめないことの大切さを改めて実感しました...！**
:::

今後は、これに ***GitHub Actions を組み合わせることで、低コストでのCI/CD環境を実現できる可能性がある***と考えています。

いつかのタイミングで、さらに深掘りして挑戦してみたいと思います。***この内容がどなたかの技術の支えになれば幸いです。***

## 参考記事

https://dev.classmethod.jp/articles/deploying-to-aws-lambda-container-using-github-actions/

https://qiita.com/sasaco/items/b65ce36c05c50a74ac3e

https://qiita.com/Kyohei-takiyama/items/86e71e1f4f989bbfc665