概要
AWS Lambdaのruntime nodejs16.x
のサポートが来年6月で切れまーす!
みなさまのお手元にはこの震えるようなAWS(またはクラスメソッドさん)からのメールは届いていますか?
つまりそれは、nodejs12.x,14.xから16.xと逃げ回って遂に18.xへの対応をやらなければならないときが来ましたということです、年貢の納めどきです。
具体的にはライブラリのバージョンを上げたり、過去の互換を捨てたものは変更したり、ソースコードをなおしたりとやることはめんどくさく、作業は泥臭いものになります。
それでも先に進むというみなさま、覚悟はいいですか?
・・・では進みましょう。
ざっくりやることのリスト
これが全てではないと思いますが、移行を主眼として必ずやらないといけないことを列挙します。
1. serverless.{yml|ts} の変更
runtimeを変更しました。
16から20...
これで2年+αくらいは追い回されずにすむはずです。
2. serverlessおよびpluginのバージョンを上げる。
どこまで上げればいいかはserverlessプロジェクトでnodejs18対応された段階までだと思いますが・・最新にしとけばいいと思います。
執筆時点では "serverless": "3.38.0",
3. aws-sdk v2を利用しているdependecyを探す
下記のコマンドを打って依存関係ツリーを出力し、aws-sdk@2に依存しているライブラリをなんとかする。
npm ls --all > dependencies.txt
grep 'aws-sdk@' dependencies.txt
├─┬ aws-sdk@2.1450.0
こんなかんじの依存を見つけたらtreeをたどってv2に依存しているライブラリを特定してバージョンを上げるとかする。
ただし、serverless framework自身にこれが出ている件は、バージョンを上げればokみたいなので依存関係があってもよい例外になります。
この問題にある根幹の話は、nodejs18.x のランタイム、実行環境では 2系のaws-sdkが提供されていないということ。
そのため実行時のLogsを見ると下記のようなエラーになります。
2023-12-25T08:58:06.370Z undefined ERROR Uncaught Exception
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/src/functions/****.js\n- /var/runtime/index.mjs",
"stack": [
"Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'",
"Require stack:",
"- /var/task/src/functions/***.js",
"- /var/runtime/index.mjs",
" at _loadUserApp (file:///var/runtime/index.mjs:1087:17)",
" at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)",
" at async start (file:///var/runtime/index.mjs:1282:23)",
" at async file:///var/runtime/index.mjs:1288:1"
]
}
まずはここと戦うことです。
ライブラリのバージョンアップに伴いソースコードを修正する
ビルド時にエラーが出ると思います。がんばってなおしましょう。
例えば下記のようなAWSに由来した関数は軒並みv3のものに置き換える必要があります。
Before(v2)
import AWS from "aws-sdk";
...
const secretsManager = new AWS.SecretsManager();
const secret = await secretsManager.getSecretValue({ SecretId: arn }).promise();
After(v3)
import { SecretsManager } from "@aws-sdk/client-secrets-manager";
...
const secretsManager = new SecretsManager();
const secret = await secretsManager.getSecretValue({ arn });
おわりに
動作確認はしっかりしましょう。
testが用意してあっても、Lambdaにのせてみないとわからないことはそれなりにある感じです。
我々の場合これでカタがつきましたが、妙に古いライブラリとかobsoletedなものを使ってるところは苦労するかもですね。