ElasticBeanstalk の環境を Node.js12 から 16 にアップデートする際の躓きポイント

# はじめに
フルカイテンではフロントの WEB サーバ構築に ElasticBeanstalk を使用しており、Node.js 12 系で開発を行っていました。
しかし ElasticBeanstalk の Node.js12 プラットフォームは2023/02/01 時点で既に EOL を迎え、 リタイア状態となっています。
環境を複製できなかったり、セキュリティ面でのサポートも切れているため、早期に開発環境の Node.js バージョンアップと EB の Node16 プラットフォームを使用した新しい環境を作成する必要がありました。
実際に作業を行うと色々と躓いたポイントがあったため、本記事ではその具体的な内容と解決策を紹介します。

# 本記事の対象読者
- ElasticBeanstalk(Node.js@12 Platform) で WEB サーバを構築している
- Node.js のバージョンを12系から16系にアップデートする予定がある

# バージョンアップ時の躓きポイント
## (1) 環境のクローンができない
Beanstalk のプラットフォームのブランチアップデート（今回のように Node12 から 16 にあげるような場合）では、環境のクローンを作成したりすることはできません。
Beanstalk はマネージドサービスのため多種多様な設定項目がありますが、（コード管理していない場合） **すべてのパラメータを目視で確認し同設定を反映する必要があるのか...？** と一瞬絶望しました。
が、実際はそんなことはありません。
Beanstalk には現在の設定されているオプションを yaml で出力するという便利機能があります。　
今回は、プラットフォームブランチのアップデートのみが目的のため、以下の手順で新しい環境を作成することができました。

### 既存環境設定を引き継いで、新規環境を作成する
#### 1. 現在稼働している環境の設定ファイルを保存する

[AWS の公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environment-configuration-savedconfig.html) を参考に現在稼働している環境の設定ファイルを保存後、 yaml ファイルを DL します。

#### 2. 保存した yaml ファイルを複製し、 PlatformArn 指定を書き換える
今回は Node12 から Node 16 へプラットフォームブランチの変更のみ実施しました。
```diff_yaml:new-eb-config.yaml（us-east-1リージョンの場合)
Platform:
-  PlatformArn: arn:aws:elasticbeanstalk:us-east-1::platform/Node.js 12 running on
-    64bit Amazon Linux 2/5.5.0
+  PlatformArn: arn:aws:elasticbeanstalk:us-east-1::platform/Node.js 16 running on
+    64bit Amazon Linux 2/5.6.3
```

#### 3. 変更した yaml ファイルから新しい環境を作成する

```bash
# プラットフォームを変更した yaml のファイル名を指定して、設定ファイルをアップロード
$ eb config put eb-new-config
# eb create $｛新しい環境名} --cfg {設定ファイル名} で設定ファイルから新しい環境を作成する
$ eb create new-eb-node16 --cfg eb-new-config --sample
```

以上の手順だけで、既存環境の設定を引き継いだ、新しいプラットフォーム(Node.js16)の環境を作成することができます。
※ 新しい環境の作成は、`ebcli` を使用していますがコンソール上から行うことも可能です。

## (2) node-sass のバージョン不整合
これで、新しいプラットフォーム(Node16)の環境はできたので、あとはデプロイするだけ…と思っていたら、今度は EB デプロイ時にエラーが発生しました。
ローカル環境では一切発生していないエラーで、なぜ Beanstalk のインスタンスだけ...?と色々調べていたら、
原因は **node-sass と npm のバージョン不整合** でした。
[node-sassの公式](https://github.com/sass/node-sass#node-version-support-policy) にも対応している Node バージョンのサポートポリシーが記載されています。

- ローカルの開発環境ではパッケージ管理ツールに yarn を使用していた
- Beanstalk の Node.js プラットフォームは yarn ではなく npm を使用する

上記の問題により、 Beanstalk 環境でのみエラーが発生していました。
今回は node-sass は未使用のパッケージだったため、 package.json から node-sass の記載を削除するだけで問題は解消しました。


## (3) npm のアップデートによる husky install エラー
(2) の問題を解消し、再度 Beanstalk にアプリケーションをデプロイすると、また違うエラーが発生していました。
```bash
husky install

sh: husky: command not found
npm ERR! code 127
npm ERR! command failed
npm ERR! command sh -c husky install
```

[husky](https://typicode.github.io/husky/#/) はGitのコミットやプッシュなどの特定のアクションが起こった時、リントなど任意のコマンドを実行できる開発者ツールで、フルカイテンでもコード品質の担保のために使用しています。
今回エラーになっている husky install は package.json の prepare で指定していました。
 ※ husky の公式ドキュメントでも prepare に記述するように記載されています
こちらも調査をしたところ、以下が原因でした。

**・ Nodeアップデートに伴う npm のバージョンアップにより、prepare コマンドが実行されるようになったこと**

▼ npm の Github にも issues　が上がっています。

https://github.com/npm/cli/issues/4027 

対応方法はいくつかあり、[husky の issues](https://github.com/typicode/husky/issues/914) でも議論されていますが、
今回は ignore-scripts というオプションを Beanstalk 環境でのみ true にする ( prepare コマンドを実行しない）という手法で対応しました。

手順は以下の[プラットフォームフックファイル](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html)を、Beanstalk のデプロイアーティファクト(zip) に含めるだけです。
```bash:.platform/hooks/prebuild/01_npm_set_ignore_scripts.sh
#!/bin/bash
npm set ignore-scripts true
```

上記のファイルを含めて再度デプロイすると、正常にデプロイが完了し、Node16 環境でアプリケーションが動作することを確認できました:tada:


# おわりに
本記事の内容以外にも「FULL KAITEN V3」の開発で工夫した点、改善点、苦労した部分などまだまだあります。

また、Rust、Athena、PySparkでビッグデータ処理に関わりたいエンジニアも募集しています。

会社概要は[こちら](https://corp.full-kaiten.com/index.html#career)です！
フルカイテンの note は[こちら](https://note.com/fullkaiten_re/)です！
Youtube は[こちら](https://www.youtube.com/channel/UCL7DtuTyW9-udcNP9_e5wrQ)です！

ぜひご覧ください！！