はじめに
半年近くブログをサボっていた宮本です。意識していないと、なかなか書かないですね……。
今回はTerraformでNodeランタイムのAWS Lambdaを複数同時に作成しようとしたとき、遭遇した問題とその解決策についてご紹介しようと思います。
問題の発生した構成
業務でAWSを利用する際は基本的にTerraformを利用しており、Lambdaの管理もTerraformで実施しています。ただしLambdaはコンテナ形式では無く、昔ながらのコードをzipで固めてデプロイする形式にしていました。
このLambdaはNode.jsのランタイムを利用しており、コード自体はTypeScriptで開発してデプロイ時にterraform_dataリソースを使ってビルドしています。また、パッケージ管理にはyarn v1を利用していました。
1 2 3 4 5 6 7 8 9 10 11 12 |
resource "terraform_data" "build_code" { provisioner "local-exec" { working_dir = "${path.module}/app" command = <<EOT #!/bin/sh # 依存関係のインストール yarn install # ビルドコマンドの実行 yarn build EOT } } |
これ単体は正常に動作していたのですが、1つのプロジェクト内で同様の構成のLambda複数デプロイしようとしたところyarn install
のタイミングでエラーが発生するようになってしまいました。
1 |
error https://registry.yarnpkg.com/<パッケージパス>: Integrity check failed for "<パッケージ名>" (computed integrity doesn't match our records, got "<ハッシュ>") |
terraform_data同士に依存関係もないためTerraform上で同時にyarn install
が動作したらしく、さらにこの2つのyarn install
でインストールするパッケージに同一パッケージの異なるバージョンが含まれていたため、エラーが発生してしまったようです。
解決方法
今回試した限りでは、次の2種類の方法どちらかで回避できました。
- yarnの実行時にキャッシュディレクトリを指定する
- yarn v1の利用をやめてpnpmやyarn v4に移行する
yarnの実行時にキャッシュディレクトリを指定する
yarnはパッケージのインストール時に、次回以降のインストールを高速にするためキャッシュを保存します。これがyarn v1だと、該当のプロジェクトではなくPC全体のグローバルなキャッシュとして保存しています。
今回は同一パッケージの別バージョンをよりにもよって同時にinstallしようとしたため、そのキャッシュ周りがおかしくなったことが直接の原因でした。
この解決策としては、実行時にyarnのキャッシュディレクトリを指定することで対処できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
resource "terraform_data" "build_code" { provisioner "local-exec" { environment = { # キャッシュフォルダを指定 YARN_CACHE_FOLDER = ".yarn-cache" } working_dir = "${path.module}/app" command = <<EOT #!/bin/sh # 依存関係のインストール yarn install # ビルドコマンドの実行 yarn build EOT } } |
yarn v1の利用をやめてpnpmやyarn v4に移行する
もう一つの解決策として、yarn v1の利用をやめることがあります。
同じyarnでもv4だとグローバルキャッシュ周りの動作が改善されているらしく、同じプロジェクトでも問題は発生しませんでした。また、pnpmでも試してみましたがこれも問題は発生しませんでした。
最新のパッケージ管理ツールだと、パッケージ同士の依存関係のバージョン差分の問題なども解決してくれるため、こちらの方がスマートな気はします。もっとも、パッケージ管理ツールを移行するとなると足が重いのも事実ですが……。
少なくとも、今後新しいNode.jsのプロジェクトを利用する場合は、最新のパッケージ管理ツールを利用したいですね。
おわりに
今回は、Terraformから複数のNode.jsのプロジェクトをビルドしようとした際に発生したエラーについて紹介しました。必ずしも発生する問題ではないと思いますが、もしyarn v1を利用していて似たような自体が発生した際に参考になれば幸いです。