1
0

serverless frameworkで作ったLambda Function についてnodejs16.x以下のバージョンをnodejs18.xに上げるためのメモ書き

Posted at

概要

AWS Lambdaのruntime nodejs16.x のサポートが来年6月で切れまーす!
みなさまのお手元にはこの震えるようなAWS(またはクラスメソッドさん)からのメールは届いていますか?

つまりそれは、nodejs12.x,14.xから16.xと逃げ回って遂に18.xへの対応をやらなければならないときが来ましたということです、年貢の納めどきです。

具体的にはライブラリのバージョンを上げたり、過去の互換を捨てたものは変更したり、ソースコードをなおしたりとやることはめんどくさく、作業は泥臭いものになります。

それでも先に進むというみなさま、覚悟はいいですか?

・・・では進みましょう。

ざっくりやることのリスト

これが全てではないと思いますが、移行を主眼として必ずやらないといけないことを列挙します。

1. serverless.{yml|ts} の変更

runtimeを変更しました。
16から20...
これで2年+αくらいは追い回されずにすむはずです。

image.png

image.png

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なものを使ってるところは苦労するかもですね。

参考とした記事や情報

1
0
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
0