[ 小ネタ ] LocalStackでNode.js18のLambdaを動かす場合はPROVIDER_OVERRIDE_LAMBDA=asfを設定する

2023.03.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部Delivery部のアベシです。

ランタイムがNode.js18のLambda関数をLocalStack上に立ち上げた際に実行エラーとなりハマったので、どうすれば動くようになるのか調べた事を紹介したいと思います。

まず結論

現行バージョンのLocalStackでNode.js18を使用するにはLocalStack起動の際にPROVIDER_OVERRIDE_LAMBDA=asfを指定する必要がありました。

事象

まずはハマった際にLocalStackでどのようにLambda関数を実行して、どんなエラーが発生したかについて紹介します。

実行環境

LocalStack CLIを使用して以下の環境で行いました。

項目名 バージョン
mac OS Ventura 13.2
localstack 1.4.0
Docker 20.10.21

LocalStackは Docker上で動作しますので、Dockerのインストールが必要です。

LocalStack上でLambda関数作成

以下のコマンドでLocalStackを立ち上げます。

$ localstack start

以下の結果が返り、最後にReady.と表示されれば立ち上げ完了です。

     __                     _______ __             __
    / /   ____  _________ _/ / ___// /_____ ______/ /__
   / /   / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
  / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
 /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|

 ? LocalStack CLI 1.4.0

[19:39:40] starting LocalStack in Docker mode ?                                          localstack.py:138
────────────────────────────── LocalStack Runtime Log (press CTRL-C to quit) ──────────────────────────────
Waiting for all LocalStack services to be ready
2023-03-21 10:39:40,796 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
2023-03-21 10:39:40,797 INFO supervisord started with pid 16
2023-03-21 10:39:41,806 INFO spawned: 'infra' with pid 21
2023-03-21 10:39:42,870 INFO success: infra entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

LocalStack version: 1.3.2.dev
LocalStack Docker container id: 4701b6725227
LocalStack build date: 2023-02-09
LocalStack build git hash: c2bd5b6f

Ready.

Node.js18でLambda関数作成

続いて以下のコマンドでLocalStack上にLambda関数を作成します。 ランタイムはNode.js18を指定しています。

aws lambda create-function \
--function-name sample-function \
--zip-file fileb://function.zip \
--handler function.handler \
--runtime nodejs18.x \
--role arn:aws:iam::123456789012:role/lambda-execute \
--endpoint-url=http://localhost:4566

Lambda関数は以下の内容をzip圧縮して使いました。

exports.handler = async function(event, context) {
return context.logStreamName
}

関数の実行

lambdaを実行します。 コマンドは以下の公式情報を参考にしました。

aws lambda invoke \
--function-name sample-function out\
--log-type Tail \
--endpoint-url=http://localhost:4566

Unhandledというエラーが発生しました。

{
  "StatusCode": 200,
  "FunctionError": "Unhandled",
  "LogResult": "",
  "ExecutedVersion": "$LATEST"
}

Unhandledは日本語だと未処理という意味になるようです。 ということは処理自体走っていない?
処理が走っていないということはランタイムが動かなかったのかも?と推測しました。

ランタイムをNode.js16に変更してみる

ということで別のランタイムならどうかと思い、試しにNode.js16に変更してみました。

aws lambda create-function \
--function-name sample-function \
--zip-file fileb://function.zip \
--handler function.handler \
--runtime nodejs16.x \
--role arn:aws:iam::123456789012:role/lambda-execute \
--endpoint-url=http://localhost:4566

実行

{
    "StatusCode": 200,
    "LogResult": "G1szMm1TVEFSVCBSZXF1ZXN0SWQ6IGU3ZThiZjBkLTg5ZWQtMWQzNC00MjE1LTE2ZDM3MjcyMjZjMyBWZXJzaW9uOiAkTEFURVNUG1swbQobWzMybUVORCBSZXF1ZXN0SWQ6IGU3ZThiZjBkLTg5ZWQtMWQzNC00MjE1LTE2ZDM3MjcyMjZjMxtbMG0KG1szMm1SRVBPUlQgUmVxdWVzdElkOiBlN2U4YmYwZC04OWVkLTFkMzQtNDIxNS0xNmQzNzI3MjI2YzMJSW5pdCBEdXJhdGlvbjogODQuNjQgbXMJRHVyYXRpb246IDEuNzMgbXMJQmlsbGVkIER1cmF0aW9uOiAyIG1zCU1lbW9yeSBTaXplOiAxNTM2IE1CCU1heCBNZW1vcnkgVXNlZDogNTAgTUIJG1swbQ==",
    "ExecutedVersion": "$LATEST"
}

今回は正常に動いてくれました。

LocalStackがNode.js18に対応していない?

ということでLocalStackがNode.js18に対応していないかもしれないと推測し調べるとGitHubで以下のやり取りがありました。

LocalStackのメンバーのDanielさんによると、Node.js18を使うなら新しいlambda providerを使用するようにと言ってます。
使用するにはPROVIDER_OVERRIDE_LAMBDA=asfを指定する必要が有るとのことなのでLocalStack起動の際に試してみました。

PROVIDER_OVERRIDE_LAMBDA=asf を指定してLocalStackを起動してみる

LocalStackの起動コマンドにPROVIDER_OVERRIDE_LAMBDA=asf追加して起動します。

PROVIDER_OVERRIDE_LAMBDA=asf localstack start

Node.js18のLambda関数の作成と実行

もう一度先程のコマンドでlambda関数をNode.js18で作成して、実行してみます。

{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiAzNWE5OThlYi0yMTAwLTQzYzItYTEyOS0yYjE2Yjc4MzQ3OWMgVmVyc2lvbjogJExBVEVTVApFTkQgUmVxdWVzdElkOiAzNWE5OThlYi0yMTAwLTQzYzItYTEyOS0yYjE2Yjc4MzQ3OWMKUkVQT1JUIFJlcXVlc3RJZDogMzVhOTk4ZWItMjEwMC00M2MyLWExMjktMmIxNmI3ODM0NzljCUR1cmF0aW9uOiAzLjMzIG1zCUJpbGxlZCBEdXJhdGlvbjogNCBtcwlNZW1vcnkgU2l6ZTogMTI4IE1CCU1heCBNZW1vcnkgVXNlZDogMTI4IE1CCQo=",
    "ExecutedVersion": "$LATEST"
}

今度はNode.js18でも正常に動きました。

新しいlambda providerとは?

先ほど出てきたlambda providerですが、 LocalStackの公式ページに Lambda Provider の古いタイプと新しいタイプが両方つかえる事が書いてました。

現在のLocalStackのバージョンではデフォルトは古いタイプとなっており、新しい方を使用するにはPROVIDER_OVERRIDE_LAMBDA=asfを明示する必要があるようです。 また、バージョン2.0移行は新しいタイプのLambda Providerがデフォルトとなるとのことでした。

以上。