Cloud9でLambda(Python)を作り始めるメモ

AWS Cloud9でLambda開発の環境構築に多少作業が必要だったのでまとめておきます。
既にあちこちでまとめられているけど自分用に。AWS初心者です。

## 前提
- OS：Amazon Linux 2023
- インスタンスタイプ：t2.micro(無料枠)
- 接続：AWS Systems Manager(SSM)

## 導入作業
### pyenvの追加とPythonバージョン変更
まずはPythonバージョンを確認。
```bash
$ python --version
Python 3.9.16
```
サポート期限まで約1年半(2024/2時点)か～～～となったのでバージョン変更できるようにしておきます。まずはpyenvの導入から。
個人的な好みとしては.bash_profileではなく.bashrcに書き込めばよかった…と反省。
```bash
$ sudo yum -y update
$ sudo yum -y install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel git libffi-devel
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```
　参考：[pyenvを用いたpython環境構築手順（CentOS7.1）](https://qiita.com/ksugawara61/items/ba9a51ebfdaf8d1a1b48)

 これでpyenvでPythonのバージョン管理ができるようになりました。
 ```bash
 $ pyenv --version
 pyenv 2.3.35-13-gaca9af76
 ```
 というわけで早速Pythonを最新版に…と行きたいところなんですが、Cloud9でLambda関数をデバッグするときに使用するライブラリとして「ikp3db」というパッケージが必要になります。どうやらこのikp3dbは現時点でPython 3.11以降に対応していないらしい。
 　参考：https://github.com/cmorisse/ikp3db

というわけで3.10系を入れます。
```bash
$ pyenv install --list
// インストール可能なPythonバージョン一覧が出るのでbugfix最新バージョンを確認 //
$ pyenv install 3.10.13
$ pyenv global 3.10.13
$ python --version
Python 3.10.13
$ pip install --upgrade pip
$ pip --version
pip 24.0 from /home/ec2-user/.pyenv/versions/3.10.13/lib/python3.10/site-packages/pip (python 3.10)
```
これで一応Pythonの準備は完了です。

### Lambdaプロジェクトの実行エラー対策
AWS ExplorerからLambdaのHello Worldプロジェクトを作成します。Cloud9上の操作については割愛。以下記事の「作成」の手順でPython3.10を選んだだけです。template.yamlやlaunch.jsonは触ってません。
　参考：[Cloud9でLambdaを作る（ユーザーガイドをなぞる編）](https://qiita.com/a_b_/items/6b02e08ecacdd21524c2#%E4%BD%9C%E6%88%90)

再生ボタンを押してみたらいろいろエラーが出ました。順番に対策していきます。

#### ikp3dbの導入
ikp3dbというパッケージが見つからないというエラーが出ていたので、パッケージを追加します。ログファイルのエラーメッセージは以下。
```
[ERROR]: SamLaunchRequestError: SAM build failed: PythonPipBuilder:ResolveDependencies - {ikp3db==1.4.2(sdist)} [BuildFailure]
```
作成したLambdaプロジェクトのフォルダに移動し、以下コマンドを実行します。
```bash
$ pip install ikp3db --target .
$ python -m venv venv
$ venv/bin/pip install --upgrade pip
$ venv/bin/pip install ikp3db
```
これでとりあえずikp3db関連のエラーは出なくなりました。
　参考：[【AWS】Cloud9でLambdaのデバッグが出来なくなった際の対応（Python）](https://qiita.com/y-okuhira/items/9244562fe47664a9d7b9)
#### EBSストレージ拡張
次はこんなエラーが発生。コンテナが…存在しない…？
```
[ERROR]: SamLaunchRequestError: SAM build failed: Container does not exist. Cannot get logs for this container [BuildFailure]
```
どうやらCloud9を初期値で作成した場合、EBSストレージのボリュームが不足してエラーになるようです。
　参考：[新しく作ったCloud9環境でpythonのsam buildに失敗する場合の原因と解決法](https://qiita.com/kinocoffeeblack/items/4daf1b6440cf3e1c25da)

ひとまず以下を参考にストレージのボリュームを30GiBに設定。初期値が10GiBのようなので、とりあえず現行の無料枠最大値に拡張してみました。
　参考：[【画像あり】AWS Cloud9の容量不足を解決する方法](https://cmqblog.com/aws-cloud9-ebsvolume-expand/)
 
合計30GiBなので、スナップショットとか作ると課金が発生する点には注意が必要です。うっかりするとすぐお金を吸われそう。個人開発だと怖いところですね。

### Lambdaプロジェクトの検証
#### ローカル実行
まずはLambdaのプロジェクトフォルダ(template.yamlがある階層)で以下コマンドを実行。
```bash
$ sam local start-api
* Running on http://127.0.0.1:3000
```
上記の通り「127.0.0.1:3000」(localhostのポート3000)でリクエストを受け付けているので、新しくターミナルを開いて以下を実行。
```bash
$ curl http://127.0.0.1:3000/hello
{"message": "hello world"}
```
というわけでレスポンスとしてhello worldが返ってきていることが確認できました。

#### Runボタンから実行
Runボタン右側のプルダウンから「API xxx」を選択すると`sam local start-api`を実行した場合のデバッグ、「xxx」を選択すると`sam local invoke`を実行した場合のデバッグが可能です。多分。
ただしこっちではreturnの中身は見られず、GETに成功したかどうかだけ分かります。
```
2024-02-12 16:43:27 127.0.0.1 - - [12/Feb/2024 16:43:27] "GET /hello HTTP/1.1" 200 -
```

### デプロイ
1. S3に適当なバケットを作成
1. AWS ExplorerのLambdaを右クリックして「Deploy SAM Application」を選択
1. スタック名はプロジェクト内で関数のprefixにしたい言葉を入力

これでLambda関数の生成とS3バケットになんか色々出力されていました。
ソース変更時は同じ手順を実行すると同じLambda関数が更新されていましたが、S3のtemplateファイルなどは追加になっていたのでいらなくなったら適宜削除すべき？
エラーになる場合は以下の②対処を試してみる。
　参考：[CLIが利用できない初歩的な見落とし](https://qiita.com/docdocdoc/items/d847ec8c0390c04b6279)

 ## おわりに
 AWSのサービスは更新が頻繁に入るのでまた躓くんだろうなぁ…と感じたので、環境壊したときにやり直せるよう記録していきたいですね。
 先人の皆さんの情報公開に感謝。