1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人ブログのバックエンドを EC2 から Lambda に移行した

Posted at

はじめに

 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 関数を指定する。

image

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 も食いつぶしていた個人ブログ:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?