LoginSignup
5
6

More than 5 years have passed since last update.

【AWS】 LambdaでNode.jsネイティブモジュールを利用する

Posted at

はじめに

Node.jsランタイムのLambda上で、firebase-adminモジュールを利用してfirestoreを操作しようとしたときエラーが起きました。
エラーが起きた原因はfirebase-adminで利用しているgrpcがネイティブモジュールであることが原因で解決できたのでメモ程度にまとめました。

Lambdaとは

AWSのFunction as a Serviceです。
Httpリクエストやスケジューリングでイベントを発火して、事前に用意しておいたコードを実行させることができます。
Nodejs、Python、Ruby、Java、Go、.NETで書かれたコードを実行させることができます。

Lambdaの環境

・オペレーティングシステム – Amazon Linux
・AMI – amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2
・Linux カーネル – 4.14.77-70.59.amzn1.x86_64
・AWS SDK for JavaScript – 2.290.0
・SDK for Python (Boto3) – 3-1.7.74 botocore-1.10.74

Node.jsのネイティブモジュールとは

Node.jsで利用できるモジュールの中にC/C++で書かれているものがあります
そのようなモジュールはクロスプラットフォームのコマンドラインツールでビルドしてから利用できるようになっています。
そのようなモジュールはネイティブモジュールと呼ばれ、ビルドされたモジュールは違うOSでは動かないことが多々あります。

つまり、MacやWindowsPCのローカル環境でネイティブモジュールをインストールして、そのモジュールを利用したコードを書きLambdaで実行させようとするとOSの違いでうまく動かないことがあるということです。

Lambdaでネイティブモジュールを利用する方法

Lambdaでネイティブモジュールを利用したい場合、Amazon LinuxというOSで動くモジュールを準備する必要があります。
Amazon Linuxの環境を構築して、その環境内でモジュールをインストールすればいいので、Dockerの出番です。

Dockerが使えない場合、Dockerを使えるようにしておいてください。

Amazon LinuxのContainer起動

AmazonはAmazon Linuxのイメージを公開しているので、プルしましょう。

docker pull amazonlinux:latest

PCのボリュームをマウントして、Amazon Linuxイメージでコンテナーを対話モードで起動します。

※下記のコマンドではtempというフォルダをマウントしています。

docker run -it -v $PWD/temp:/temp --name native-module-sample amazonlinux:latest

Node.jsを利用できるようにする

rpmを利用できるようにする。

curl -sL https://rpm.nodesource.com/setup_8.x | bash -

yumでネイティブモジュール利用に必要なものをインストールする。

yum install gcc-c++ make

yumでパッケージマネジャーのyarnをインストールする。

curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
yum install yarn

yumでNode.jsをインストールする。

yum install -y nodejs gcc-c++ make

これで、8系のNode.jsとnpmが利用できるはずです。

ネイティブモジュールをインストールしてみる

ローカルPCのtempフォルダをマウントしているので、マウント先でネイティブをインストールします。

※下記のコマンドではfirebase-adminをインストールしています。firebase-admin内で利用しているgrpcがネイティブモジュールです。

cd temp
npm init -y
npm install firebase-admin

インストールが終了したら、ローカルPCのマウントしているフォルダを確認しましょう。
node_modulesができているはずです。

nodejs/node_modules/*の構成でzip化してLambda Layerとしてアップロードしましょう。

後は、Layerを登録したLambdaにモジュールを利用したコードをアップロードすれば実行できるはずです。

さいごに

ローカル環境ではうまく動くのにLambda上では動かない原因として、ネイティブモジュールが関わっている場合もあります。エラーで行き詰まっていたら一度ネイティブモジュールの存在も疑ってみてもいいかもしれません。

参考

DockerでAWS Lambda用のNode.jsネイティブモジュールをビルドする

5
6
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
5
6