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

# はじめに

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

https://nodejs.org/ar/blog/announcements/nodejs16-eol/

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

https://aws.amazon.com/jp/blogs/compute/node-js-18-x-runtime-now-available-in-aws-lambda/

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

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

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

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

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

◎見つけたissue(byteLength関連（認証周り？）)

https://github.com/aws/aws-sdk-js-v3/issues/2282

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

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

# より実装面で、、、

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

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/migrating-to-v3.html

<strong>V3のコード</strong>
```js
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();
```

<strong>V2のコード</strong>
```js
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がエラーで終了する。」という事が起こります。
  
https://github.com/aws/aws-sdk-js-v3/blob/main/UPGRADING.md   
  
<strike> V3側のブログの、</strike>  
   
<strike>Client Constructors</strike>   
   
<strike>のパラメータの置き換え（V3移行の時は、ここの置き換えやらないといけない）と、機能単位の読み込みという所で、細かい所で、「こう動きべきだよね」という所でもエラーになる。（デフォルト値の挙動がおかしい）</strike>   
   
<strike>Firehoseクライアント（V3）をLambdaから使った場合、「Default Credential Provider」の「environmental variable」を暗黙的にセットしてくれない。</strike>    
<strike>V2の時は、上記が出来ていた。（これは出来るのが正しい挙動（下記）だと思う。。。）</strike>   
   
<strike>https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/loading-node-credentials-lambda.html</strike>   
   
<strike><抜粋>～～</strike>
<strike>実行ロールは、実行と他のウェブサービスを呼び出すために必要な認証情報を Lambda 関数に提供します。その結果、Lambda 関数内で記述した Node.js コードに<strong>認証情報を提供する必要はありません。</strong></strike>
<strike>～～<抜粋></strike>   
   
<strike>V3では、Node.jsコードで、明示的に「Default Credential Provider」の認証情報を生成して、各機能のクライアントに設定するのが、普通になる、、、かもしれない？、まだ情報が少ないので、この辺り、公式にも問い合わせするかもしれません。
</strike>

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

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

# V2 のレイヤー（Lambdaの機能）を用意

```sh
npm install aws-sdk
```

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

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

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html

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

![レイヤー階層.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/6f19c1bc-0460-b04d-03bf-86918645cd75.jpeg)

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

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

```sh
zip -r AwsSdkV2Layer.zip ./nodejs
```

#  LambdaにAWS SDK（V2）のレイヤーを作成


![レイヤー登録_1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/184a00a0-d98e-cd14-3b29-b01229f7e465.jpeg)

![レイヤー登録_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/7dedf361-4b4b-ce48-6a7d-d518037a3151.jpeg)

![レイヤー登録_3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/f7c846a4-1d8e-a909-3481-4aef1a32da95.jpeg)

![レイヤー登録_4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/362c3aff-4b88-70d5-5777-162e15c11b5b.jpeg)

![レイヤー登録_5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/634aaf1a-75a1-5e67-490a-728f995bd973.jpeg)

![レイヤー登録_6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281768/bf7024c5-2bc6-c171-5e97-4888d93e1373.jpeg)

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

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

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

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

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

https://www.cs-cloud-aid.com/