これは?
pythonのFastAPIで作成したAPIをAWSの色々なサービスと連携させて動かしてみるよ。
流れは以下。
- FastAPI + dockerでAPIを作る。
- 1をECR/ECSで動かす。
- 2をLambdaで動かす。
- 1をDynamoDBとの連携にする。
- 4をLambda Web Adapterで動かす。
1. FastAPI + dockerでAPIを作る。
作成するAPIは、簡単な利用者登録機能。以下、2つの機能を持つ。
- 指名と年齢をリクエストして登録できる。(post)
- 登録されている全員の情報を取得できる。(get)
DBはまずは使わず、data.csvに吐き出して使う。
作成したコード
できること
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"%
FastAPIやdockerの利用方法は、色んな記事があるので割愛。
2. 1をECR/ECSで動かす。
1はあくまでローカルで動くものなので、これをAWSのECR/ECSで動くようにする。
2-1. ECRの用意
マネージメントコンソールからElastic Container Registryを選択。
画面左のpublic repositoryから、リポジトリの作成を選択
リポジトリ名を「ecr_work」にして作成。
これで、以下のようにECRのリポジトリが出来上がる。
2-2. ECRにdockerイメージをpush
ECRのリポジトリをクリックして右上に出てくる「プッシュコマンドの表示」を参考にする。
上記そのままだが、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は、コンソールのログイン名の「セキュリティ認証情報」から取得できる。
次に、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されたイメージが確認できる。
これで、ECRへのdocker imageのpushは完了。
2-3. ECSで動かす
ECRにpushしたdockerイメージを動作させるためにECSに登録する。
まず、ESCにアクセスし、「クラスター」を選択する。
クラスタ名を指定し、インフラストラクチャにFargateを指定する。
次に、タスク定義を作成する。「新しいタスク定義の作成」をクリックし、新しいタスク定義の作成を選択する。
タスク定義名を指定し、
インフラストラクチャの要件は、fargeteを指定。タスクロールに、ecsTaskExecutionRoleを指定。
コンテナの箇所には、名前は任意に指定。
イメージURIは、ECRのURIをセットする。
コンテナポートとポート名の箇所は、FastAPIを8000ポートで扱っているため、8000を8000にフォワードするように指定しておく。(不要かも??80ポートアクセスを8000に変えるためとかでこう言うのはセットする気がする。)
ログ収集の設定も以下のように入れておく。
デフォルトでセットされているため、そのままでOK。
タスク定義が作成できたら、再度クラスターに戻り、今度はサービスを追加する。
クラスターでクラスタ名をクリックした後の画面から以下を表示させ、下のサービスの「作成」をクリックする。
デプロイ設定は、アプリケーションタイプにタスクを選択し、ファミリーに先ほど作成したタスク定義名を指定する。
ネットワーキングは、セキュリティグループに8000ポートのアクセスを許可するセキュリティグループを指定する。
※ セキュリティグループの作成は、マネコンから「セキュリティグループ」で検索して作成していく。
今回はガバガバだけど、全てのIPからの:8000ポート接続を許可する。
これでECSの設定は完了。
タスクにて、以下のようにステータスが実行中になれば準備完了。
2-4. ECSでの動作確認
ECRのタスクをクリックすると、詳細情報が確認できる。
ここで、パブリックIPを確認して動作確認をする。
ブラウザで8000ポートでアクセスすると、以下の結果を得て動作が確認できる。
また登録と、全員の情報を取得する動作も確認する。
登録
$ 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"%
登録後、再度全員の情報を取得すると、tumikickがちゃんといる。
cloudwatchのログも確認しておく。
ちゃんと、標準出力がログとして残っている。
コード
shell配下に、ecrへのpushを追加している。
2をLambdaで動かす。
動かそうとしたけど、動かなかった・・・。
logを吐き出そうとしてエラーになってて、/tmp/配下に出すようにしないといけないっぽい?
後日やってみようと思う