10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LambdaのランタイムVerUp(Node.js 16.x → Node.js 18.x)の課題と移行アプローチについて

Last updated at Posted at 2022-12-09

はじめに

本来はNode.js 16はLTSで2024/4までサポート期間がありましたが、OpenSSL 1.1.1のサポート終了に合わせて7ヶ月繰り上げられています。

Lambdaを利用したサービスを相当数開発しており、2024年までは安定稼働させられると考えていた矢先に、早々(2023/09)にNode.jsのバージョンアップを検討しないといけないようです。

幸い、Node.js 18のサポートは開始されいる。

移行に当たって、どれ位、コード修正なしで動作するか検証した所、多大な修正が必要だったので、バージョンアップは計画的に!という注意喚起と、誰かの参考になればという事でメモ書きします。

バージョンアップ検証において分かった課題

  • バンドルされる「AWS SDK」のバージョンが変わる(V2 → V3)
  • 単純な置き換えコード修正でも動作しないクライアント(Firehose)がある(credentials関連の扱いが変わってそう)

ハマった issue

「AWS SDK V3」は海外のコミュニティなどでもissueに上がってましたが認証周りの挙動が怪しいので、時期尚早感があるように感じました。

◎見つけたissue(byteLength関連(認証周り?))

移行アプローチ

Lambda で「AWS SDK V3」使えるのは嬉しい?ですが、「AWS SDK V2」を、いきなりバッサリ捨てるのは難しい。現実問題として結構な量のコード修正をしないといけないので、今回は下準備に留める。

極力、「AWS SDK V2」→「AWS SDK V3」への移行をしやすいようにコードをリファクタリングしつつ、ランタイムは、Node.js 18に切り替えて、「AWS SDK V2」で動作させるという方針にしました。

より実装面で、、、

公式:「コードをSDK for SDK に移行します JavaScript V3」より

V3のコード

import {S3} from '@aws-sdk/client-s3';
const client = new S3({region: 'us-west-2'});
const bucketParams = {
    Bucket : BUCKET_NAME
};
function run(){
         client.createBucket(bucketParams, function(err, data) {
         if (err) {
         console.log("Error", err);
         } else {
         console.log("Success", data.Location);
         }
    })
};
run();

V2のコード

var Aws     = require('aws-sdk');
var client = new Aws.S3();
const bucketParams = {
    Bucket : BUCKET_NAME
};
function run(){
         client.createBucket(bucketParams, function(err, data) {
         if (err) {
         console.log("Error", err);
         } else {
         console.log("Success", data.Location);
         }
    })
};
run();

aws-sdk全体を読み込む(V2)か、機能毎に細かく読み込む(V3)か?という違いですが、何も対処をしないで、Lambdaのランタイムを、Node.js 18にランタイムを変更すると、V2がバンドルされてないので、「require('aws-sdk');」の段階で「「Not Found」のエラーでLambdaがエラーで終了する。」という事が起こります。

V3側のブログの、

Client Constructors

のパラメータの置き換え(V3移行の時は、ここの置き換えやらないといけない)と、機能単位の読み込みという所で、細かい所で、「こう動きべきだよね」という所でもエラーになる。(デフォルト値の挙動がおかしい)

Firehoseクライアント(V3)をLambdaから使った場合、「Default Credential Provider」の「environmental variable」を暗黙的にセットしてくれない。
V2の時は、上記が出来ていた。(これは出来るのが正しい挙動(下記)だと思う。。。)

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/loading-node-credentials-lambda.html

<抜粋>~~
実行ロールは、実行と他のウェブサービスを呼び出すために必要な認証情報を Lambda 関数に提供します。その結果、Lambda 関数内で記述した Node.js コードに認証情報を提供する必要はありません。
~~<抜粋>

V3では、Node.jsコードで、明示的に「Default Credential Provider」の認証情報を生成して、各機能のクライアントに設定するのが、普通になる、、、かもしれない?、まだ情報が少ないので、この辺り、公式にも問い合わせするかもしれません。

2021/12/16修正
FirehoseはputRecordに渡す引数の型が変更されているのが判明したので、別記事にまとめました。

ひとまずはV3のissuesが、もっと消化されるのを待ちたい。(2022/12/09時点で、319個)、だいぶ枯れたV2を継続したいが、Node.jsは 18.X に上げたい。というお話が、今回の話になります。

V2 のレイヤー(Lambdaの機能)を用意

npm install aws-sdk

で、登録用の「AWS SDK(V2)」を取得する。

Lambda側で読み込むディレクトリ階層(パス名)が決まっているので階層作成

xray-sdk.zip
└ nodejs/node_modules/aws-xray-sdk

レイヤー階層.JPG

実際のディレクトリ階層(フォルダ階層)は、上記のような階層構造です。

カレントディレクトリを、「nodejs」の直上のディレクトリになるように移動して、下記のコマンドで、Zipファイルを作成します。

zip -r AwsSdkV2Layer.zip ./nodejs

LambdaにAWS SDK(V2)のレイヤーを作成

レイヤー登録_1.JPG

レイヤー登録_2.JPG

レイヤー登録_3.JPG

レイヤー登録_4.JPG

レイヤー登録_5.JPG

レイヤー登録_6.JPG

まとめ

AWS Lambdaの「AWS SDK V3」は、結構、大掛かりなコード修正が必要である。

だがしかし、Node.jsのLTS都合上、2023/09までには、「Node.js 18.X」にしないといけない。

Node.js 18.X のデフォルトでは、「AWS SDK V2」は使えないので「(当面)V2を使い続ける(レイヤーでSDKを自分で管理)」か、「V3に移行する為にコード大改修(不具合に対するワークアラウンド込)をする」の、2択を迫られている事に、多くのLambda(on Node.js)ユーザに気付いて欲しいです。

AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。

10
7
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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?