はじめに
EC2 & ALB はコストが高すぎた。1 円にもならない個人ブログのために 1 か月 $40 という大金が消えていた。そのうち移行しよう、なんて甘い考えだったが、マネジメントコンソールのコストを見ていたら居ても立っても居られなくなった。
なぜだかわからないがとても不安になった。
そこで急遽移行を始めた。
Lambda 関数の作成
幸いバックエンドは複雑なコードではなく、index.js という 1 つのファイルだけだった。ChatGPT にどのようにデプロイしたらよいか聞いた。
AWS Lambdaは、ファイルシステムへの長期的なアクセスや常駐プロセスの保持を前提としていないため、標準的なExpressサーバーのコードをそのままLambdaにデプロイすることはできません。ただし、AWS LambdaでExpressアプリケーションを実行するために、aws-serverless-expressなどのライブラリを使用してHTTPリクエストを処理する形に変換することが一般的です。
aws-serverless-express
を使うらしい。コードも書いてもらった。
import awsServerlessExpress from 'aws-serverless-express'; // 新規追加
// 他は現行コードのまま
// サーバーをAWS Lambdaに対応させる
const server = awsServerlessExpress.createServer(app);
export const handler = (event, context) => {
return awsServerlessExpress.proxy(server, event, context);
};
最後の部分は以下のリッスンする処理を削除して書き換える。
const port = 8080;
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
よくわからないが、書き換えたものを Lambda 関数コードに貼り付けデプロイした。
レイヤー作成手順
次にレイヤーを作成する。
mkdir lambda-layer # 適当な作業ディレクトリ
mkdir next-blog-app # このアプリの作業ディレクトリ
mkdir nodejs # レイヤー作成に必須のディレクトリ
vi package.json # GitHub で管理している package.json をコピペする
npm install
cd ..
zip -r next-blog-app.zip nodejs
この後、マネジメントコンソール画面で、Lambda > レイヤー > レイヤーの作成 の順に進み、 zip 化したファイルをアップロードする。
require を import に書き換える
レイヤーを作ってコードをデプロイしたらテストする。
require is not defined in ES module scope, you can use import instead
テストしたら上記エラーが出たのでパッケージの使用は require ではなく import に書き換える。
レイヤー更新
次のエラーは以下:
Cannot find package 'aws-serverless-express' imported from /var/task/index.mjs
EC2 で動かしていたころのパッケージには aws-serverless-express
は含まれていなかったので、レイヤーに追加する必要があった。レイヤーを作り直す。
npm install aws-serverless-express
cd ..
zip -r next-blog-app.zip nodejs
API Gateway で REST API を作成する
ルートパス直下に {proxy+}
リソースを作り、ANY メソッドで Lambda 関数を指定する。
CORS 設定を有効化し、API をデプロイする。
まとめ
aws-serverless-express
を初めて使った。めんどくさい設定が必要かと思ったら意外と簡単だった。今まで 1 つの API に 1 つの Lambda 関数を関連付けていたが、ANY メソッドと {proxy+}
リソースと謎のコードによって 1 つにまとめることができることを知った。
const server = awsServerlessExpress.createServer(app);
export const handler = (event, context) => {
return awsServerlessExpress.proxy(server, event, context);
};
移行後早速 EC2 インスタンスを停止し、ALB を削除した。今月既に $20 だ。もっと早く移行すればよかった。悔やんでも仕方ない。
1か月 $40 も食いつぶしていた個人ブログ: