はじめに
本来は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の時は、上記が出来ていた。(これは出来るのが正しい挙動(下記)だと思う。。。)
<抜粋>~~
実行ロールは、実行と他のウェブサービスを呼び出すために必要な認証情報を 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
実際のディレクトリ階層(フォルダ階層)は、上記のような階層構造です。
カレントディレクトリを、「nodejs」の直上のディレクトリになるように移動して、下記のコマンドで、Zipファイルを作成します。
zip -r AwsSdkV2Layer.zip ./nodejs
LambdaにAWS SDK(V2)のレイヤーを作成
まとめ
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の活用方法や、お困りごとの相談、随時、お仕事の受付しております。