AWS Lambdaでレイヤーを作成する方法とディレクトリ構成でハマった話

# 目次

1. [はじめに](#Chapter0)
2. [用語解説](#Chapter1)
3. [作業の目的](#Chapter2)
4. [誤った作業](#Chapter3)
5. [エラー発生](#Chapter4)
6. [解決方法](#Chapter5)
7. [参考文献](#reference)

# はじめに

AWS Lambdaのレイヤーを作成する際にディレクトリ構成でハマった話と、その解決方法をシェアします。
レイヤーを使うと共通のライブラリや依存関係を複数のLambda関数で使い回せて便利ですが、正しいディレクトリ構成が必要です。
今回はそのディレクトリ構成についての注意点と、エラーの解決方法について説明します。

<a id="#Chapter1"></a>
# 1. 用語解説

## Lambdaとは

AWS Lambdaは、Amazon Web Services（AWS）が提供するサーバーレスコンピューティングサービスです。
普段、プログラムを動かすにはサーバー（コンピュータ）が必要ですが、Lambdaではそのサーバー管理をAWSが代わりに行ってくれます。
開発者はプログラムのコードを書くことに集中できるのです。
Lambda関数はイベントが発生したときに自動的に実行され、必要なだけのリソースをAWSが自動で割り当ててくれます。

例えば、ウェブサイトでユーザーがフォームを送信したとき、そのデータを処理するコードをLambda関数として実行できます。
Lambdaは、プログラムの処理をAWSが全てやってくれるので、開発者はプログラムの内容だけを考えれば良いという便利なサービスです。

## レイヤーとは

AWS Lambdaレイヤーは、Lambda関数で使うライブラリや依存関係をまとめておくための仕組みです。
ライブラリとは、プログラムの機能を追加するための部品のようなものです。
例えば、データベースにアクセスするためのライブラリがあれば、そのライブラリを使って簡単にデータベースに接続できます。

レイヤーを使うと、複数のLambda関数で同じライブラリを共有でき、効率的に管理できます。
レイヤーはZIPファイルとして作成され、Lambda関数に追加して使用します。
これにより、開発者は必要なライブラリを簡単に利用でき、コードの管理がしやすくなります。

<a id="#Chapter2"></a>
# 2. 作業の目的

AWS Lambdaのレイヤーは、共通のライブラリや依存関係を複数のLambda関数で共有するための方法です。
レイヤーを使用すると、コードの再利用が容易になり、Lambda関数のデプロイメントが効率化されます。
レイヤーは、Lambda関数で使用されるライブラリ、カスタムランタイム、その他の依存関係を含むZIPファイルです。
これを作成してLambda関数に追加することで、必要なライブラリを一箇所にまとめて管理できます。

<a id="#Chapter3"></a>
# 3. 誤った作業

レイヤーを作成する際に、正しいディレクトリ構成でZIPファイルを作成しなければなりません。
具体的には、以下のような構成でレイヤーを作成する必要がありました：

```
S3BackupCheck_SharedLayer/
└── python/
    ├── env.py
    └── messages.py
```

ここで `S3BackupCheck_SharedLayer` は任意のフォルダ名です。
このフォルダ名は、自分が使用するレイヤーの目的に応じて自由に決められます。
例えば、特定のプロジェクトや機能に関連する名前を付けることが一般的です。

<font color="Red">しかし、誤って`S3BackupCheck_SharedLayer`フォルダ全体を圧縮してしまいました。</font>
その結果、解凍すると期待されるディレクトリ構成とは異なる形になってしまいました。

<a id="#Chapter4"></a>
# 4. エラー発生

この間違ったディレクトリ構成でレイヤーを作り、Lambda関数を実行すると、`env.py`や`messages.py`が見つからず、以下のようなエラーが出ました：

```
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'env'
Traceback (most recent call last):
```

<a id="#Chapter5"></a>
# 5. 解決方法

正しいレイヤーを作るためには、以下の手順でディレクトリを構成し、圧縮します。

## 正しいディレクトリ構成

1. `python`フォルダを作成し、その中に必要なファイル（例：`env.py`、`messages.py`）を配置します。

```
S3BackupCheck_SharedLayer/
└── python/
    ├── env.py
    └── messages.py
```

## 圧縮コマンド（CLI）

2. `python`フォルダの中身を圧縮して、ZIPファイルを作成します。

```powershell
Compress-Archive -Path .\python\* -DestinationPath ..\S3BackupCheck_SharedLayer.zip -Force
```

このコマンドは、`python`フォルダ内の全てのファイルとフォルダを圧縮して、`S3BackupCheck_SharedLayer.zip`という名前のZIPファイルを作成します。

## GUIで圧縮

1. `python`フォルダを右クリックし、`送る` → `圧縮（ZIP形式）フォルダ`を選択します。
2. 作成されたZIPファイルの名前を`S3BackupCheck_SharedLayer.zip`に変更します。

## 解凍時のディレクトリ構造の確認（CLI）

3. 解凍時に正しいディレクトリ構成であることを確認します。

```powershell
Expand-Archive -Path "C:\Path\To\S3BackupCheck_SharedLayer.zip" -DestinationPath "C:\Path\To\temp_dir" -Force
Get-ChildItem -Recurse "C:\Path\To\temp_dir"
```

期待される出力：

```
temp_dir/
└── python/
    ├── env.py
    └── messages.py
```

## 解凍時のディレクトリ構造の確認（GUI）

1. `S3BackupCheck_SharedLayer.zip`ファイルを右クリックし、`すべて展開`を選択します。
2. 解凍先のフォルダを指定し、解凍された内容が正しいディレクトリ構造であることを確認します。

<a id="#reference"></a>
# 参考文献
- [AWS Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html)
- [AWS CLI Documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)