FastAPIでのAPIをAWSの色々なサービスと連携させて動かす

## これは？
pythonのFastAPIで作成したAPIをAWSの色々なサービスと連携させて動かしてみるよ。
流れは以下。

1. FastAPI + dockerでAPIを作る。
2. 1をECR/ECSで動かす。
3. 2をLambdaで動かす。
4. 1をDynamoDBとの連携にする。
5. 4をLambda Web Adapterで動かす。

### 1. FastAPI + dockerでAPIを作る。
作成するAPIは、簡単な利用者登録機能。以下、2つの機能を持つ。
- 指名と年齢をリクエストして登録できる。(post)
- 登録されている全員の情報を取得できる。(get)

DBはまずは使わず、data.csvに吐き出して使う。

#### 作成したコード
https://github.com/ys201810/webapp_toy/tree/v0.1.0_local_ver/backend

#### できること
POSTでユーザー追加

```
$ curl -X 'POST' 'http://127.0.0.1:8000/save_person' \
  -H 'accept: application/json' -H \
  'Content-Type: application/json' \
  -d '{"name": "kaede", "age": 21}' 
> "save success name:kaede age:21"%
```

GETでユーザー情報取得
![スクリーンショット 2024-01-07 10.05.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/2a6adfde-245c-13b4-c417-d51657593ebf.png)

FastAPIやdockerの利用方法は、色んな記事があるので割愛。

### 2. 1をECR/ECSで動かす。
1はあくまでローカルで動くものなので、これをAWSのECR/ECSで動くようにする。

#### 2-1. ECRの用意
マネージメントコンソールからElastic Container Registryを選択。

![スクリーンショット 2024-01-07 11.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/a969ff0c-bee4-6ce6-e46f-ad3af4fb3eec.png)

画面左のpublic repositoryから、リポジトリの作成を選択

![スクリーンショット 2024-01-07 12.00.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/0657feca-c123-f56b-6277-bca0b8cb30a4.png)

リポジトリ名を「ecr_work」にして作成。
これで、以下のようにECRのリポジトリが出来上がる。

![スクリーンショット 2024-01-07 12.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/74083781-3bc4-c950-e7ff-d64f07fc4440.png)

#### 2-2. ECRにdockerイメージをpush
ECRのリポジトリをクリックして右上に出てくる「プッシュコマンドの表示」を参考にする。

![スクリーンショット 2024-01-07 12.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/38d4702f-515c-bd65-d1e8-7b5a8cb5b2ab.png)

![スクリーンショット 2024-01-07 12.05.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/737e1dfb-b4eb-774a-a8ec-ca19aa2aba3e.png)

上記そのままだが、awscliをインストールしておく必要がある。
awscliは、pipでインストールしておく。

```
$ pip install awscli
```

その後、以下のコマンドを実行する。

```
$ aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/q9x9g6a9
> Login Succeeded
```

※ このコマンドの実行前に、`aws configure`で、Acess Key IDとSecret Access Keyをセットする必要があった気がする。Access Key IDとSecret Access Keyは、コンソールのログイン名の「セキュリティ認証情報」から取得できる。

![スクリーンショット 2024-01-07 12.11.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/f478b2a0-62e0-eb7a-42c6-f4252e04f069.png)

![スクリーンショット 2024-01-07 12.12.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/724d423c-ead0-b4d2-c9f4-8b9881950824.png)

次に、docker buildでdocker imageを作成する。

```
$ docker build -t ecr_work .

$ docker images
> REPOSITORY                             TAG       IMAGE ID       CREATED       SIZE
> ecr_work                               latest    792e0636c9fa   2 hours ago   1.28GB
```

そして、docker imageにtag名をつける。

```
$ docker tag ecr_work:latest public.ecr.aws/q9x9g6a9/ecr_work:latest

$ docker images
> REPOSITORY                             TAG       IMAGE ID       CREATED       SIZE
> public.ecr.aws/q9x9g6a9/ecr_work       latest    792e0636c9fa   2 hours ago   1.28GB
> ecr_work                               latest    792e0636c9fa   2 hours ago   1.28GB
```

最後にtagを付与したdocker imageをECRにpushする。

```
$ docker push public.ecr.aws/q9x9g6a9/ecr_work:latest
```

pushが成功すると、ECRの画面で以下のように、pushされたイメージが確認できる。
![スクリーンショット 2024-01-07 12.19.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/726658e0-6686-dc86-d85a-37bb54db040d.png)

これで、ECRへのdocker imageのpushは完了。

### 2-3. ECSで動かす
ECRにpushしたdockerイメージを動作させるためにECSに登録する。

まず、ESCにアクセスし、「クラスター」を選択する。

![スクリーンショット 2024-01-07 12.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/8c6fac1e-455e-a5c1-3e22-b050dcfea97d.png)

クラスタ名を指定し、インフラストラクチャにFargateを指定する。
![スクリーンショット 2024-01-07 12.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/8a126c39-e8f2-4b7b-74b5-bfe4dabd109e.png)

次に、タスク定義を作成する。「新しいタスク定義の作成」をクリックし、新しいタスク定義の作成を選択する。

![スクリーンショット 2024-01-07 12.30.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/3f534cd5-6ae7-37f4-f8b9-5374063817f5.png)

タスク定義名を指定し、

![スクリーンショット 2024-01-07 12.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/db4c5798-ec3d-0ede-402c-f713c139525f.png)

インフラストラクチャの要件は、fargeteを指定。タスクロールに、ecsTaskExecutionRoleを指定。

![スクリーンショット 2024-01-07 12.32.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/77ed085a-e07d-8c5c-ba78-71c505236eaf.png)

コンテナの箇所には、名前は任意に指定。
イメージURIは、ECRのURIをセットする。
コンテナポートとポート名の箇所は、FastAPIを8000ポートで扱っているため、8000を8000にフォワードするように指定しておく。（不要かも？？80ポートアクセスを8000に変えるためとかでこう言うのはセットする気がする。）

![スクリーンショット 2024-01-07 12.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/2747091c-135d-b88a-b5b5-a790767700cf.png)

ログ収集の設定も以下のように入れておく。
デフォルトでセットされているため、そのままでOK。

![スクリーンショット 2024-01-07 12.37.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/867d16e8-d9ee-9308-f429-4a5b8646634c.png)

ストレージの量の箇所は、最小の21を指定しておく。
![スクリーンショット 2024-01-07 12.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/811b4577-3356-0bd2-63c8-118f791b2a8f.png)

ECRのURIの確認場所
![スクリーンショット 2024-01-07 12.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/1221e633-f438-2dde-dbac-13bafb67e2d2.png)

タスク定義が作成できたら、再度クラスターに戻り、今度はサービスを追加する。
クラスターでクラスタ名をクリックした後の画面から以下を表示させ、下のサービスの「作成」をクリックする。

![スクリーンショット 2024-01-07 12.40.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/f7810887-df45-ed9b-ad10-07431052f9a6.png)

コンピューティングオプションは起動タイプを選択。
![スクリーンショット 2024-01-07 12.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/41a5e492-7dff-9833-4142-97311529fb16.png)

デプロイ設定は、アプリケーションタイプにタスクを選択し、ファミリーに先ほど作成したタスク定義名を指定する。
![スクリーンショット 2024-01-07 12.43.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/0cd0781c-8b91-5cdb-ab10-8dcf3f8e2086.png)

ネットワーキングは、セキュリティグループに8000ポートのアクセスを許可するセキュリティグループを指定する。
![スクリーンショット 2024-01-07 12.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/91a9c6fc-c63a-e4a1-2a4a-d7757013f49b.png)

※ セキュリティグループの作成は、マネコンから「セキュリティグループ」で検索して作成していく。
![スクリーンショット 2024-01-07 12.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/9179af6c-4d55-03de-4c85-cab303bad1be.png)

今回はガバガバだけど、全てのIPからの:8000ポート接続を許可する。
![スクリーンショット 2024-01-07 12.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/df9e05a3-9b70-46fe-ffae-2df0413f2800.png)

これでECSの設定は完了。
タスクにて、以下のようにステータスが実行中になれば準備完了。

![スクリーンショット 2024-01-07 13.31.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/0fd8ecc5-5edb-5f82-5f73-fb12dbec1a73.png)

### 2-4. ECSでの動作確認
ECRのタスクをクリックすると、詳細情報が確認できる。

![スクリーンショット 2024-01-07 13.32.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/adfc7dc3-a6c0-8fa0-3a7f-c4c4aa6574d0.png)

ここで、パブリックIPを確認して動作確認をする。

ブラウザで8000ポートでアクセスすると、以下の結果を得て動作が確認できる。
![スクリーンショット 2024-01-07 13.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/5ece7b63-cbbf-0df7-6893-5c50d36d9ad3.png)

また登録と、全員の情報を取得する動作も確認する。

![スクリーンショット 2024-01-07 13.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/dbf8b7ad-e817-4593-214d-4c061e21443f.png)

登録

```
$ curl -X 'POST' 'http://3.112.235.11:8000/save_person' \
  -H 'accept: application/json' -H \
  'Content-Type: application/json' \
  -d '{"name": "tumikick", "age": 44}'
> "save success name:tumikick age:44"%
```

![スクリーンショット 2024-01-07 13.35.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/778602ad-ef55-97c6-2022-382a195502d1.png)

登録後、再度全員の情報を取得すると、tumikickがちゃんといる。

cloudwatchのログも確認しておく。

![スクリーンショット 2024-01-07 13.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549365/3a75166e-849a-cf25-96dd-ca84000ddb77.png)

ちゃんと、標準出力がログとして残っている。

### コード
https://github.com/ys201810/webapp_toy/tree/v0.1.1_ecrecs_ver/backend

shell配下に、ecrへのpushを追加している。

### 2をLambdaで動かす。
動かそうとしたけど、動かなかった・・・。
logを吐き出そうとしてエラーになってて、/tmp/配下に出すようにしないといけないっぽい？
後日やってみようと思う

## 参考
[awscliのインストール](https://zenn.dev/hayato94087/articles/7848e9d6a2e3d6)