LocalStack と CDK で遊んでみる (3) — Web アプリに挑戦
目的
何となく SAA-C03 を受けてみたいが、本だけ読んで勉強するのはつらいので手を動かしたい。ので、少しそれっぽいことを CDK + LocalStack でやりたいなというもの。
ちょうど AWS CDK+localstackを使ってよくあるRESTなWebアプリ構成を作ってみる という素晴らしい記事があったので、内容を読みつつ少し読み替えて実装してみたい。
LocalStack と CDK で遊んでみる (2) 以来の久しぶりの CDK ネタでもある。
開発環境
- Ubuntu 20.04
- Docker version 24.0.5, build ced0996
- npm 9.8.1
- node v18.17.1
- LocalStack 2.2.0
- cdklocal 2.93.0 (build 724bd01)
- aws-cli 2.13.13
実装
基本的に AWS CDK+localstackを使ってよくあるRESTなWebアプリ構成を作ってみる のままだが、少し変更する。
- Lambda の Python: 3.9 → 3.10
- 外部 PC からの実行を想定して CORS の設定を Lambda に追加
ソースコード: https://github.com/derwind/cdk-study/tree/rest-web-app
docker-compose.yml
Accessing localstack from another computer を参考に、以下を変更:
version: "3.8"
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack:2.2.0
ports:
- "4566:4566" # ここを変更
...
web/package.json
Viteで起動したローカル開発サーバーにIPアドレスで外部からアクセスする方法【Vue3/Typescript編】 を参考に、以下を変更:
{
"name": "web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --host --port 8080", // ここを変更
...
web/.env
スタックのデプロイ後のログを参考に VITE_REST_API_ROOT_URL
をリモートサーバの URL に変更:
VITE_REST_API_ROOT_URL=http://xxx.xxx.xxx.xxx:4566/restapis/yyyyyyyyyy/prod/_user_request_/
CORS (Cross-Origin Resource Sharing) の設定
毎回よく分かっていないので宜しくはないのだが[1]、今回のパターンでは、各 Lambda の戻り値に CORS の設定を追加すれば良さそうであった。内容は雑なので、もっと適切に設定すべきではある:
def handler(event, context):
...
return {
"statusCode": 200,
"body": json.dumps({"res": results, "event": event}),
"headers": { # CORS の設定
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD",
"Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
},
}
動作確認
~/.aws/credentials
[localstack]
aws_access_key_id = test
aws_secret_access_key = test
という設定にしておいて、以下を順に実行していく:
LocalStack 起動
docker compose up -d
Bootstrap
cd app
cdklocal bootstrap aws://000000000000/us-east-1
スタックのデプロイ
cd app
cdklocal deploy
Web アプリの起動
S3 に Web アプリをデプロイした場合、LocalStack を動かしている PC 内からは CfnOutput
した URL へのアクセスでいけたのだが、外部 PC からは名前解決できそうになかったので諦めて dev サーバ上で確認することにした:
cd web
npm run dev
画面イメージは以下の通り:
まとめ
一番手こずったのは CORS の設定の部分なのだが、何とかこの構成でも適用して別 PC からアクセスすることができた。
今回の内容に近いことは既に何回かやったことはあるのだが、実際の AWS でやっていて LocalStack では初めてだったので動くかどうか試してみたかったのがあった。
これで、SAA-C03 に向けての “無料の AWS 環境” が用意できたような気がする[2]。
Appendix
BucketDeployment の件
参考にした AWS CDK+localstackを使ってよくあるRESTなWebアプリ構成を作ってみる では BucketDeployment
が使えないとあるが、仮に使うとどうなるか試した。結論として、スタックのデプロイは通って、S3 にバケットも作成されるのだが、当該バケットに下に何もオブジェクトがデプロイされていないという状況になった
import {
...
aws_s3_deployment as s3deploy
} from 'aws-cdk-lib';
export class AppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
...
new s3deploy.BucketDeployment(this, "DeployWebsite", {
sources: [s3deploy.Source.asset("./website-dist")],
destinationBucket: websiteBucket,
destinationKeyPrefix: "web/static",
});
...
}
}
雑多なデバッグ用の色々 (メモ)
Lambda 一覧
aws --profile localstack lambda list-functions
API Gateway 一覧
aws --profile localstack apigateway get-rest-apis
CloudWatch Logs
ロググループを確認
aws --profile localstack logs describe-log-groups
ロググループ内のログストリームを確認
aws --profile localstack logs describe-log-streams --log-group-name "/aws/lambda/RegisterData"
ロググループ内の指定ログストリームの内容を確認
わりとハマりどころとして、[$LATEST]
と表示される部分を [\$LATEST]
にしないとならない。
aws --profile localstack logs get-log-events --log-group-name "/aws/lambda/RegisterData" --log-stream-name "2023/08/29/[\$LATEST]7ae57eaea31e16f0f00b724e8639425a"
-
@aws_cdk/aws-apigatewayv2-alpha を使う場合や、Lambda 関数 URL を使う場合でそれぞれちょっとずつ設定が違うのだが、本質は何なんだろう? ↩︎
-
どうせマネジメントコンソールではほとんど操作しないから、基本機能が動けば本物の AWS でも LocalStack でもどちらでも良いのである。 ↩︎
Discussion