[AWS] LocalStackの学習まとめ

## ✏️学習前の認識
- DockerでAWSの仮想環境を作成する
- 利用できるサービスに一部制限がある
- ハンズオンというより開発時に動作確認やテストを実施するためのもの

## 初めまして「GitHub Codespaces」
こちらの記事を参考にしています。
[LocalStack 実践入門 | AWS アプリケーション開発ワークショップ](https://zenn.dev/kakakakakku/books/aws-application-workshop-using-localstack/viewer/01-setup#:~:text=GitHub-,Codespaces,-%E3%81%A7%E3%81%8D%E3%82%8B%E9%99%90%E3%82%8A%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
GitHub Codespacesの利用は初めてでしたが手順が決まっていたので問題なくセットアップできました。

## Amazon SQSキューをデプロイ
```
aws sqs create-queue --endpoint-url http://localhost:4566 \
    --queue-name chapter02-queue \
    --attributes ReceiveMessageWaitTimeSeconds=20
```
`--endpoint-url http://localhost:4566`
の部分を省略するために`LocalStack AWS CLI`を利用
```
pip install awscli-local
```

先のコマンドから`--endpoint-url http://localhost:4566`を省略したもの
```
awslocal sqs create-queue \
    --queue-name chapter02-queue-awslocal \
    --attributes ReceiveMessageWaitTimeSeconds=20
```

両方同じ結果
```
{
    "QueueUrl": "http://sqs.ap-northeast-1.localhost.localstack.cloud:4566/000000000000/chapter02-queue-awslocal"
}
```

## S3をデプロイ、そしてPythonでSQSから取得したメッセージをS3に保存
ソースは事前に準備されているので実行するだけ。
コードの解説もあるため、プログラミング学習中の人もわかりやすくなっている。
「↑それってあなたの感想ですよね」

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/2b7005f2-8644-43a6-aa38-8e940f45a063.png" width="350"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/50c42209-f848-4a53-b932-a5096bbafdb1.png" width="350">

メッセージを明示的に削除している点が自分の中でポイントだった

```app.py

# ~（略）~

for message in response.get('Messages', []):
    body = json.loads(message['Body'])
    s3.put_object(
        Bucket='chapter03-bucket',
        Key=f"{body['id']}.json",
        Body=message['Body'],
    )
    # ↓ここ
    sqs.delete_message(
        QueueUrl=queue_url,
        ReceiptHandle=message['ReceiptHandle'],
    )
```

### あれ、「可視生タイムアウト」って
- キューからメッセージを取得したらそのメッセージはキューの中で特定の間取得できなくなる
- Lambdaで処理が失敗などした場合、再度キューから取得できるような仕組み

だったよな？調べとこう

## AWS CloudFormaiton スタックをデプロイ
先日の社内LTのCI/CDテーマで「使いにくい」とコメントされてたやつか、触って経験しとこう
まずはスタックが空であることを確認
```
awslocal cloudformation describe-stacks
```
「describe」＝「説明する」らしい


## 🧠「オイオイ、なんとなく"理解"ってきたぜ」
samを触っていたからスタック自体はうっすら理解
というかCloudFormationの拡張か、ということはsamの前に触っておいた方が順序的に良かったか

まぁ過ぎたことだししょうがないか_(:3」∠)_

|用語|概要|
|-|-|
|CloudFormation|そもそものサービス、テンプレートを記述（yml形式 or json形式）|
|AWS SAM　     |CloudFormationを拡張した**フレームワーク** <br> IAMなどの記述を省略できる（うまいこと自動で作成される、←注意点を先日のJAWS-UG彩の国埼玉#0で言ってたような）|

## ワイ「この本（ワークショップ）は神か？？？」
### Chapter 05「AWS SAM使おうや」
頭にアルミホイル巻こうかな、思考読まれてないか？？？？
pythonをLambdaに乗っけてSQSからのイベントトリガーでメッセージ取得する内容
```
samlocal build
```
↓template.yamlに記述していない部分も自動で作成されている
（AWS::IAM::Role、AWS::Lambda::EventSourceMapping）
![スクリーンショット 2025-04-26 23.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/17de6da8-ebc3-4664-89e9-64d5d1b7388d.png)

### SQSにメッセージ登録してS3で確認
```
awslocal sqs send-message \
    --queue-url http://sqs.ap-northeast-1.localhost.localstack.cloud:4566/000000000000/chapter05-queue \
    --message-body '{ "id": "id0003", "body": "This is message 0003." }'
{
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/ca6e6aa9-f662-4ec9-9194-04eb0831719c.png" width="400">

## pytest と LocalStack で単体テスト
コマンドの内容というよりは`localstack_utils`の特性を解説している感じ

>また単体テストで使う LocalStack は、単体テストを実行するたびに初期化する必要があり、イミュータブルであるべきです。

こんな感じなんだろうな〜という図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/003eb08e-bcd2-4356-905f-f0ae0d096423.png" width="700">

### Lambdaベストプラクティス「ハンドラーをコアロジックから分離」
>AWS Lambda 関数のベストプラクティスの中に Lambda ハンドラーをコアロジックから分離します。 というテクニックが載っていて、ローカル環境での実行や単体テストでの実行がしやすくなるメリットがあります。

main()があったのはこういうことなのか！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391109/6ca9d87b-8c20-401d-bd9a-0fcee1a67a25.png" width="800">

もう1点ENVの環境で接続先を切り替えるのは実務でよく見るのでスキップ

pytestはpython学習時に合わせてやっていくか

## 最後はAPI Gatewayを利用するバージョン
API GatewayからLambda(sender.py)を起動
↓
SQSに登録したらイベントトリガーがLambda(receiver.py)を起動
↓
S3に登録

こんな処理
SQS以降の処理はそんなに変更がないのでpytestを解読
API Gateway~SQSまでは実有経験の範囲内の内容だったのでこれにて終了

## ワークショップを完走した感想
- localstack-cliを入れて`localstack start -d`でDockerコンテナが起動してそのまま利用可能（今回はGitHub Codespacesのポート開放が必要だった）
- GitHub Codespacesは開発環境の差異を無くすのに良いなと思った（要インターネット）
- CloudFormationから触ってAWS SAMの利便性に辿り着きたい
- awscliとawslocal、samとsamlocalはデプロイ先を間違えないように利用できそう
- ワークショップはサクッと完走できたのに内容がしっかりしている、基礎的な部分は理解できたと思う
- localstackの状況を`Resource Browser`というGUIで確認できたのがやりやすかった
- portもpriveteに変更したしこれで完了かな

### 次はReact+LambdaでToDoアプリでも作ってみるかな

今回は以上となります。

肉寿司美味しかったなぁ