はじめに
今回、LambdaランタイムNode.js8.10のサポート終了に伴い、Node.js10.xへアップデートを行いました。
結構詰まった部分などが合ったので、その備忘録として残します。
LambdaランタイムNode.js8.10のサポート終了について
以下、AWS公式より
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtime-support-policy.html
2020/2/3を持ってLambdaのランタイムNode.js8.10の更新が終了します。
これに伴い、Node.js8.10で実装しているLambdaのランタイムを10.xにバージョンアップをしました。
Lambdaのランタイム変更による変更内容
大きな変更は、コンテナ内で起動するEC2のOSがAmazon LinuxからAmazon Linux2へ変わることです。
これにより、もともとデフォルトでOSにインストールされていた、graphicsmagickと imagemagickがAmazon Linux2ではインストールされていないという状態になります。
こちらが参考記事です
https://note.com/mohya/n/n48692d8e4a57#jgl1s
つまり、Node.js10以上で、imagemagickなどを使いたい場合は、インストールしなければけません。
本記事では、この点についての対応方法を紹介します。
手順
- 単純にランタイムを変更する
- Lambdaを実行させ、エラー内容を確認する
- graphicsmagickとimagemagickのレイヤーを追加する
- Lambdaを実行させ、成功を確認する
1. 単純にランタイムを変更する
2. Lambdaを実行させ、エラー内容を確認する
以下のようなエラーが出ました。
2020-01-24T02:40:09.509Z c28c7e8b-b775-48ae-ac36-aec733c9b025 ERROR Invoke Error
{
"errorType": "Error",
"errorMessage": "Could not execute GraphicsMagick/ImageMagick: identify \"-ping\" \"-format\" \"%wx%h\" \"-\" this most likely means the gm/convert binaries can't be found",
"stack": [
"Error: Could not execute GraphicsMagick/ImageMagick: identify \"-ping\" \"-format\" \"%wx%h\" \"-\" this most likely means the gm/convert binaries can't be found",
" at ChildProcess.<anonymous> (/opt/nodejs/node_modules/gm/lib/command.js:232:12)",
" at ChildProcess.emit (events.js:198:13)",
" at ChildProcess.EventEmitter.emit (domain.js:448:20)",
" at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)",
" at onErrorNT (internal/child_process.js:415:16)",
" at process._tickCallback (internal/process/next_tick.js:63:19)"
]
}
ImageMagickが見つからず、実行できないと言われてしまっています。
3. graphicsmagickとimagemagickのレイヤーを追加する
ここがメインです。
Amazon Linux2ではImageMagickが存在しないので、インストールする必要があります。
こちらのissueが大変参考になりました。
https://github.com/ysugimoto/aws-lambda-image/issues/191
Imagemagickレイヤーの設置
サーバーレスレポジトリにて提供されているので、こちらから作成します。
https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:145266761615:applications~image-magick-lambda-layer
Gaphicsmagickレイヤーの設置
こちらは、誰か知らない人が作ってくれているので、使っちゃいます。
https://github.com/rpidanny/gm-lambda-layer
こちらは、Dockerになっていて、あれ???と思いましたが
LayerもそれぞれDockerを起動してくれ、起動時にDockerfileに記載してあるこの辺りでインストールしてくれます。
RUN curl https://versaweb.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/${GM_VERSION}/GraphicsMagick-${GM_VERSION}.tar.xz | tar -xJ && \
cd GraphicsMagick-${GM_VERSION} && \
./configure --prefix=/opt --enable-shared=no --enable-static=yes --with-gs-font-dir=/opt/share/fonts/default/Type1 && \
make && \
make install
このレイヤーをLambdaに登録しておけば、いいらしいですね。便利です。
レイヤーの適応
今回はServerless Frameworkを使用しているため、ymlで記載します。
functions:storePhotoData:handler:storePhotoData.handlerlayers:-arn:aws:lambda:ap-northeast-1:579663348364:layer:image-magick:1-arn:aws:lambda:ap-northeast-1:175033217214:layer:graphicsmagick:2-{Ref:MyLayerLambdaLayer}tracing:Activedescription:create storePhotoDatamemorySize:2048timeout:10role:storePhotoDataLambdaFunctionRole
レイヤーには実行順序という概念もあるため、レイヤーの順番も気をつけなければなりません。
MyLayerLambdaLayerはカスタマイズして作ったレイヤーで、graphicsmagickとimagemagickがないと実行できないので、念の為後ろに持ってきました。
(あんまり意味ないかも...)
4. Lambdaを実行させ、成功を確認する
ログが出せないのが申し訳ないですが、これで成功しました!!
Node.js 12.xの対応
この時どうせならと思ってランタイムをNode.js12.xにしてみたのですが、一応動きました。w
少しだけ気になる点もありましたが、恐らく大丈夫かなと思います。
一気に12へあげたい方はやってみてください。