【レポート】サーバーレスでの画像処理プラットフォーム構築ワークショップ #reinvent #ARC326

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

本記事は AWS re:Invent 2017 のワークショップ 「ARC326 - Create a Serverless Image Processing Platform」のレポートです。

画像処理といえばサーバーレスアプリケーションの筆頭ですが、サムネイルを作成するにとどまらず、ElasticSearch Service を使った画像データの検索、またそのための画像メタデータ生成まで踏み込んでいたため、とても楽しく身になるワークショップでした。

本記事では、サーバーレスアプリケーション構築の流れを説明して、最後にワークショップのポイントを整理します。

スピーカー

  • Mike Gillespie - Solutions Architect, Amazon Web Services

ワークショップの進め方

ワークショップは、 Web に構築手順書があり、それに沿って作業を進める形式でした。

  • Lambda Function 以外のリソースが詰まった CloudFormation で Create Stack
  • Lambda Function をビルド
  • Lambda Function を CloudFormation デプロイ
  • Kibana で、検索結果にサムネイルを表示できるよう設定
  • SPAをデプロイ
  • SPAで画像をアップロードする
  • ElasticSearch Service (Kibana) を使って検索する

画像アップロードでき、コンテンツとしてそれを後から検索できるという全体像です。Amazon Rekognition は、ソースコードを見る限り、画像からラベルを生成し、それを ElasticSearch Service へ追加していました。

CloudFormation による リソースの作成

あらかじめワークショップ用に CloudFormation テンプレートが用意されており、それを使ってリソースを構築します。構築されるリソースは以下です:

Logical IDs
AttachGateway
BastionProfile, BastionRole, BastionRolePolicy
CognitoApplicationClient, CognitoAuthRole, CognitoIdentityPool, CognitoIdentityPoolRole, CognitoUnauthPolicy, CognitoUnauthRole, CognitoUserPool
DeploymentBucket
ESDomain
IPAddress
InboundHTTPNetworkAclEntry, InboundResponsePortsNetworkAclEntry, InboundSSHNetworkAclEntry
InstanceSecurityGroup
InternetGateway
LambdaRolePolicy, LambdaServiceRole
NetworkAcl
OutBoundHTTPNetworkAclEntry, OutBoundHTTPSNetworkAclEntry, OutBoundResponsePortsNetworkAclEntry
Route, RouteTable
Subnet
SubnetNetworkAclAssociation
SubnetRouteTableAssociation
VPC
WebServerInstance

ArchDiagram1.79d9a73.png 引用元:ARC 326 - Create a Serverless Image Processing Pipeline

Lambda のデプロイ

Lambda Function は、先程の CloudFormation では一緒にデプロイしていません。私の考えではその理由はふたつです:

  • ElasticSearch Service のエンドポイントを Lambda Function の環境変数に設定するため
    • テンプレートをネストすれば依存関係は解決できますが、今回のようなシンプルなシステムの場合、ネストするよりも分けてしまったほうがメリットが多いという印象です
  • 今後は Lambda Function を単体でデプロイすることを想定し、Update Stack が頻繁に発生するものは別スタックとするため

さて、ワークショップでは Lambda Function 用の CloudFormation のテンプレートが用意されている状況でした。以下のようにして Lambda Function をデプロイします。

 aws cloudformation package --template-file process-image.yaml --s3-bucket arc326l8845-deploy \
--s3-prefix lambda-deploy --output-template-file process-image.packaged.yaml
 
 aws cloudformation package --template-file process-image.yaml --s3-bucket arc326l8845-deploy \
--s3-prefix lambda-deploy --output-template-file process-image.packaged.yaml
 

これで Lambda Function のデプロイまで完了します。デプロイされた Lambda Function は全部で3つありました:

Lambda Function 役割
LambdaServiceRole-ping SPAから認証が通ってるか確認するときに呼ばれます。発展課題をやるときに関係するようで、今回は使いません。
process-image 処理本体です。サムネイル作成、メタデータ読み出し、Rekognitionからラベルを生成、メタデータとラベルを ElasticSearch Service に送信します。
LambdaServiceRole-search SPAから検索要求があったときに呼ばれます。ElasticSearch Service を使って検索結果を返します。

結果として、全体像は以下のようになります。 ArchDiagram1.79d9a73.png 引用元:ARC 326 - Create a Serverless Image Processing Pipeline

検索結果でサムネイルが表示されるように Kibana を設定する

まず、 images* でインデックスパターンを定義します。これで生成されたインデックスに対して、thumbnail というフィールドがあるので、そのフィールドを以下のように設定します。

Kibana2.40db39e.png 引用元:ARC 326 - Create a Serverless Image Processing Pipeline

Type を image にし、そのURLをS3に向くよう設定することで、検索結果に画像を表示できるようになります。これで、サーバーサイドの準備は整いました。

Web アプリケーションのデプロイ

Vue.js によって作られた SPA を、S3 ウェブサイトホスティング機能を使って配信します。アプリケーションはすでに用意されており、あとはビルド・デプロイするのみです。デプロイすると以下のようなSPAが見えます。

spa.png

早速使ってみましょう。

画像をアップロードして、検索する

ワークショップで指定のあった画像を3枚アップロードし、"Lighthouse" というキーワードで検索します。すると以下のような結果が得られます。

search_result.png

この結果で注目するべきなのは以下2点です。

  • 検索結果にサムネイルが表示されている。これは、画像アップロード時にサムネイルが生成されており、そのサムネイルに対してリンクが貼られていることを示す。
  • Labels フィールドは Rekognition によって画像から自動生成されたラベルである。画像が異なっていても、"Lighthouse" という共通キーワードを持っているため、どちらも検索結果に出現する。

おわりに

サーバーレスで画像アップロード・検索アプリケーションを作る様子を、順を追って説明しました。私は、本ワークショップで以下のことを学びました。

  • Rekognition はハードルが高いイメージだったが、ラベルを自動生成するAPIをSDKから呼ぶなど簡単に機能を使える。
  • サムネイル画像生成の具体的な実装
  • ElasticSearch Service でのラベルによる検索
  • 以上のことを Lambda Function で実現できる

このワークショップには発展課題として、サーバーレスアプリケーションにおける認証や、Dead Letter Queue を利用したリトライ機構の構築、パフォーマンス改善、コスト最適化といったものが用意されています。これらについては、サーバーレスアプリケーションにおける要求課題の解決策の一例として、個別にブログにしていく予定です。