サーバーレスアーキテクチャで画像処理! Serverless FrameworkとWandで簡単構築!

サーバーレスアーキテクチャー 画像 リサイズ  こんにちは。サーバーワークス こけし部 部長でCS課の坂本(@t_sakam)です。
 前回に続いて、「Serverless Framework」の話題です。
 
 前回は、Serverless FrameworkのAPI GatewayやDynamoDBをからめた使い方をみてみました。今回はS3をからめてサーバーレスで画像処理をおこなう方法をみてみたいと思います。
 
 今回Serverless Frameworkを使って構築するのは、AWSのイベントやセミナーで「Lambdaのもっとも一般的なユースケース」としてよく紹介されている「画像処理をサーバーレスでおこなう」パターンです。
 
【画像処理をサーバーレスでおこなうユースケースを紹介している記事】
【AWS Summit Tokyo 2016】サーバーレスで構築する、マイクロサービスの未来形
 
サーバーレスで画像処理をおこなう流れ  画像処理は、Pythonのライブラリの「Wand」を使っておこないたいと思います。
 
 もちろん、前回と同じように、Lambdaファンクションのデプロイだけでなく、今回利用するS3のリソース作成もServerless Frameworkでやってしまいます。
 
  1. 「Wand」とは?
  2. Serverless Frameworkのインストール
  3. サービスの作成
  4. 必要なファイルを自動生成
  5. サービスの内容
  6. 「Wand」のインストール
  7. serverless.ymlの編集
  8. handler.pyの編集
  9. デプロイ
  10. 作成されたリソースの確認
  11. 動作確認
  12. まとめ

1. 「Wand」とは?

 「Wand」は、画像処理ツール「ImageMagick」とのインターフェイスをもっているpythonのライブラリです。
 
 「ImageMagick」はLambdaの実行環境に用意されています。あとは「Wand」を作業ディレクトリにpipでインストールして、Lambdaファンクションと一緒にアップロードするだけで、Lambdaの実行環境で使うことができます。
 
 ※AWSのドキュメント「Lambda実行環境と利用できるライブラリ」  
WandのWebトページ  

2. Serverless Frameworkのインストール

今回の作業環境

名前 バージョン
OS OS X
Python 2.7.10
aws-cli aws-cli/1.10.36
npm 2.15.5
boto3 1.3.0
Wand 0.4.3
 前回のバージョンは「v1.0.0-beta2」でしたが、正式版の「v1.0.2」がリリースされているので、以下のコマンドでローカル環境のServerless Frameworkをインストールし直します。  
 バージョンの確認ができれば、インストールは成功です。  
 ※前々回のクレデンシャル情報の設定では触れていませんでしたが、公式のドキュメントには、作業するユーザーに「AdministratorAccess」権限を付与するように書かれています。Serverless Frameworkは開発途中で、まだ必要な権限が定まらないと書かれているので、今回もいったん指示通り「AdministratorAccess」権限を付与してから作業しましょう。
 

3. サービスの作成

  インストールできたら、次はサービスを作成します。今回は「こけし」の写真をS3にアップロードすると、自動的に写真をリサイズしてくれるサービスを作りたいと思います。 サービスの作成といってもやることは、サービス用のディレクトリを作成後、そのディレクトリに入るだけです。  

4. 必要なファイルを自動生成

 以下のコマンドで必要なファイルを自動生成します。   serverless create  前回は4ファイルでしたが、今回は3つのファイルが自動生成されました。「serverless.env.yml」ファイルがなくなり、更にシンプルになっています。
  1. event.json
  2. handler.py
  3. serverless.yml

5. サービスの内容

 今回は、『S3の「kokeshi-original」バケットに写真をアップロードすると、それをトリガーにしてLambdaファンクションが実行され、写真をリサイズして「kokeshi-resize」バケットに入れる』、という流れのサービスを作りたいと思います。
 ちなみに今回は、「阿保六知秀」工人の「津軽系」こけしの写真(Tsugaru_Muchihide_Abo.jpg)をアップロードします。
 
serverless image resize
 
 ※「こけし」の場合は、作る人を「職人さん」ではなく「工人さん」と呼びます。「こけし」の「系統」についてはWikipediaの「伝統こけしの系統」をご確認ください。
 
 

6. 「Wand」のインストール

 先程作成した「kokeshi-image」ディレクトリに「Wand」をインストールします。 wand install

7. serverless.ymlの編集

 まずは、Serverless Frameworkのメインの設定ファイルであるserverless.ymlを編集します。

serverless.yml

serverless.ymlの説明

provider
 「provider」の「iamRoleStatements」を変更して、S3の操作ができるようにしたいと思います。デプロイしたときに作成されるIAMロールに、ここで指定した権限が追加されます。  
functions
 「functions」でLambdaファンクションの設定とLambdaファンクションのトリガーとなるイベントの設定をします。まず、「handler」でLambdaファンクションの設定です。「ファイル名.ファンクション名」と設定します。
 「events」でイベントハンドラーを設定します。S3をトリガーにしたい場合は、「- s3」と設定します。以下は「kokeshi-original」バケットでオブジェクトが作成されたときの設定です。  
resources
 「resources」では、CloudFormationで作成するリソースを設定します。今回はS3のバケット「kokeshi-resize」を作成します。元の画像をアップロードする「kokeshi-original」は上記の「functions」で設定しているので、「resources」で設定をしなくてもリソースが作成されます。二重で設定しないで済むのがいいですね。  

8. handler.pyの編集

 次にhandler.pyの編集です。
 
handler.py
handler.pyの説明
 イベント発生時の情報は「events」に入っています。
 まず、S3にアップロードされた画像をLambdaの実行環境の「/tmp」以下にダウンロードして、「Wand」で200px✕200pxにリサイズをおこない、元のファイル名の最後に「_resize」を付けて、その場で保存します。
 その後、リサイズした「/tmp」以下の画像をS3の「kokeshi-resize」バケットにアップロードする処理をおこなっています。
 

9. デプロイ

 これで設定ファイルとLambdaファンクションが完成したので、デプロイしてみましょう。  
 Lambdaファンクションの「arn」が返ってきていれば、成功です。 serverless deploy  

10. 作成されたリソースの確認

 デプロイが成功したら、想定していたリソースが問題なく作成されているか、マネジメントコンソールで確認してみましょう。
 
CloudFormation
 まずは、CloudFormationを確認します。「kokeshi-image-dev」というスタックが作成されています。  
CloudFormation  
 CloudFormationで作成されたリソースを確認すると、LambdaファンクションやS3の「kokeshi-original」バケットと「kokeshi-resize」バケット、Lambdaファンクションのコードのアップロード先になるバケットやIAMが作成されていることが確認できます。 CloudFormationResources  
IAMロール
 次は、IAMロールを確認します。「kokeshi-image-dev-IamRoleLambda-XXX...」という名前のロールが作成されています。  
IAM Role  
 上記のロールには以下の「dev-kokeshi-image-lambda」というポリシーがひもづいています。Serverless Frameworkでデプロイしたときにデフォルトで作成されるCloudWatch Logsのポリシーと、先ほどserverless.ymlで設定したS3の操作を許可する設定がきちんとできていることがわかります。 IAM Role Policy IAM Role Inline Policy  
Lambdaファンクション
 次は、Lambdaファンクションです。こちらもserverless.ymlで設定したLambdaファンクションのファイル名とファンクション名の設定である「handler.handler」が設定されています。ロールには先ほど確認した「kokeshi-image-dev-IamRoleLambda-XXX...」が設定されています。  
Lambda Function  
S3
 最後にS3を確認します。serverless.ymlで設定した「kokeshi-original」バケットと「kokeshi-resize」バケット、deployしたzipファイルやCloudFormationのテンプレートがアップロードされるバケットが作成されています。  
s3  

11. 動作確認

 それでは、実際に「こけし」の写真をS3にアップロードしてみたいと思います。
 元の画像の名前は「Tsugaru_Muchihide_Abo.jpg」で1000px✕1000pxです。画像を「kokeshi-original」バケットにアップロード後、「kokeshi-resize」バケットの中に「Tsugaru_Muchihide_Abo_resize.jpg」という名前で200px✕200pxにリサイズされた画像がアップロードされているかを確認します。
 
元画像の情報
元画像
画像をアップロード
s3 upload
「kokeshi-resize」バケットにリサイズ後の画像ができているのを確認
s3 resize
リサイズされた画像をダウンロードして確認
 画像がリサイズされたことが確認できました。
リサイズされた画像  

12. まとめ

 今回は、Serverless Frameworkを使ってS3をからめた画像処理の方法を試してみました。
 このようなサーバーレスでの画像処理は、Lambdaのもっとも一般的なユースケースです。まだLambdaやServerless Frameworkを使ったことがないという方は、まずはこのような処理から試してみてはいかがでしょうか?
 
 いや〜、Serverless Frameworkって本当にいいものですね。

AWS運用自動化サービス「Cloud Automator」無料トライアルはこちらから

COMMENT ON FACEBOOK