AWS lambda(Python 3.8)でimagemagickを使う

tl;dr;

AWS lambda(Python 3.8)で画像処理ツールのimagemagickを動かした。

install方法からlambda内でimagemagickの動かす際のコードまでを紹介。

imagemagickとは

imagemagick は動的に画像を編集する古典的なツール。こちらの記事によると、なんと1987年から開発されている。wikipediaを確認する限り、Photoshopのリリースが1990年だから、その古さに驚かされる。

しかしこのツール、度重なる脆弱性は報告されているものの、画像編集の機能としてまだまだ現役として使っているプロジェクトも存在する。

今回はそのimagemagickをlambdaで。Python 3.8のランタイムから使う方法を紹介する。

Serverless.Pub

ありがたい事にServerlessを支援し積極的に情報発信をしてくれている団体がいる。

彼らが作ったlambdaのbinally layerをCloudFormationでdeployする機能も提供してくれている。

https://serverless.pub/lambda-utility-layers/

GitHubはこちら

https://github.com/serverlesspub/imagemagick-aws-lambda-2

こちらをgit cloneして、make all すればimagemagickのlambdaのbinally layerができる。

その方法を使ってもよいのだが、
実は以下のページからDeployボタンを押せば、それだけで自動でCloudFormationが自分のAWSで動き、lambdaの中にbinally layerが作成されることもできる。

https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:145266761615:applications~image-magick-lambda-layer

しかし、注意すべきはここの部分。

要約すると、nodejs10.xランタイムのようなAmazon Linux 2で使えるよ。とのこと。PythonのPの字も見当たらない。
対象外かと思い当初諦めていた。

そんな中、最近、Python 3.8ランタイムがlambdaで使えるようになった事を知り、公式ドキュメントを読んでみると、今までのPythonで使っていたOSとは異なり、Amazon linux2がベースとなっていることがわかった。

node.jsに絞っているのはAmazonLinux2がベースのように見受けられたため、これはlambdaの中でPythonでもimagemagickを動かせるかもと思い今回試す事にした。

やってみた

https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:145266761615:applications~image-magick-lambda-layer

を開きDeployボタンを押す。
しかし、この時点でいきなりDeployされるわけではない。

DeployはCloudFormationによって行われる。CloudFormationのスタック名確定させたら(デフォルトでもよい)デプロイを押下。

しばらくすると、AWS LambdaのLayersに新たにimage-magickが登録される。

Lambda関数から、Layersを選択する

レイヤーの追加ボタンを押し、imagemagickを選択する。

レイヤーに表示されない場合は、以下のようにARNを直接入力する。

これで下準備は完了

AWS lambda(Python 3.8)でimagemagickを使う

 ここからがPythonからimagemagickを使えるかの確認。

今回はシンプルにversionを表示させることで使える事にしたい。

コードはこちら。

subprocessを使って、Pythonから、lambdaが動いているOS側のコマンドを実行する。

imagemagickをinstallすると使えるようになるconvertコマンドを叩く。

 

結果は以下の通り

無事imagemagickのversionを確認できた。

最後に

私が実施した際はレイヤーの追加ボタンを押しても選択肢としてimagemagickが表示されなかった。

これは、CloudFormationによって作られるimagemagickのレイヤーがnode.jsに限定しているため。不便なのでpull reqを出してmergeしてもらった。

https://github.com/serverlesspub/imagemagick-aws-lambda-2/pull/18/files

今はレイヤー選択画面から互換性のあるレイヤーとして選択できるはずだ。