チュートリアル: Amazon S3 で AWS Lambda を使用する
バケットにアップロードされる各画像ファイルのサムネイルを作成するとします。オブジェクトの作成時に Amazon S3 が呼び出すことができる Lambda 関数 (CreateThumbnail
) を作成できます。その後、Lambda 関数はソースバケットから画像オブジェクトを読み取り、ターゲットバケットにサムネイル画像を作成できます。
このチュートリアルを完了すると、アカウントで以下の Amazon S3、Lambda、および IAM リソースが作成されます。

Lambda のリソース
-
Lambda 関数。
-
Amazon S3 に Lambda 関数を呼び出すアクセス許可を付与する Lambda 関数に関連付けられたアクセスポリシーです。
IAM のリソース
-
このロールに関連付けられたアクセス権限ポリシーを使用して Lambda 関数に必要なアクセス許可を付与する実行ロールです。
Amazon S3 のリソース
-
Lambda 関数を呼び出す通知設定を持つソースバケット。
-
関数がサイズ変更された画像を保存するターゲットバケットです。
前提条件
このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。まだ作成していない場合は、「AWS Lambda の開始方法」の指示に従って、最初の Lambda 関数を作成します。
次のステップを完了するには、コマンドを実行するコマンドラインターミナルまたはシェルが必要です。コマンドは、該当する場合、プロンプト記号 ($) と現在のディレクトリの名前が前に付けられて、リストに示されます。
~/lambda-project$ this is a command
this is output
コマンドが長い場合は、エスケープ文字 (\
) を使用して、コマンドを複数の行に分割します。
Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。Windows 10 では、Linux 用の Windows サブシステムをインストール
関数の依存関係を管理するには、npm をインストールします。
このチュートリアルでは、AWS CLI コマンドを使用して Lambda 関数を作成し、呼び出します。ASK CLI をインストールし、AWS 認証情報を使用して設定します。
実行ロールを作成する
AWS リソースにアクセスするためのアクセス権限を関数に付与する実行ロールを作成します。
実行ロールを作成するには
-
IAM コンソールの [Roles] ページ
を開きます。 -
[ロールの作成] を選択します。
-
次のプロパティでロールを作成します。
-
[信頼されたエンティティ] – [AWS Lambda]。
-
[Permissions (アクセス許可)] – [AWSLambdaExecute]。
-
ロール名 –
lambda-s3-role
。
-
AWSLambdaExecute ポリシーには、Amazon S3 でオブジェクトを管理してログを CloudWatch Logs に書き込むために関数が必要とするアクセス許可があります。
バケットを作成しサンプルオブジェクトをアップロードする
バケットを作成し、オブジェクトをアップロードするための手順を行います。
-
Amazon S3 コンソール
を開きます。 -
バケットを 2 つ作成します。ターゲットバケット名は、
source
とその後に-resized
を連結したものになる必要があります。ここで、source
は、ソースに使用するバケットの名前です。たとえば、mybucket
とmybucket-resized
です。 -
ソースバケットで、.jpg オブジェクトの
HappyFace.jpg
をアップロードします。Lambda 関数を手動で呼び出すときは、Amazon S3 に接続する前に、ソースバケットと新しく作成されるオブジェクト (
HappyFace.jpg
) を指定するサンプルイベントデータをその関数に渡します。そのため、最初にこのサンプルオブジェクトを作成する必要があります。
関数を作成する
以下のコード例では、Amazon S3 イベント入力を受け取り、含まれるメッセージを処理します。ソースバケットのイメージのサイズを変更し、ターゲットバケットに出力を保存します。
他の言語によるサンプルコードについては、「サンプル Amazon S3 関数コード」を参照してください。
例 index.js
// dependencies const AWS = require('aws-sdk'); const util = require('util'); const sharp = require('sharp'); // get reference to S3 client const s3 = new AWS.S3(); exports.handler = async (event, context, callback) => { // Read options from the event parameter. console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); const srcBucket = event.Records[0].s3.bucket.name; // Object key may have spaces or unicode non-ASCII characters. const srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")); const dstBucket = srcBucket + "-resized"; const dstKey = "resized-" + srcKey; // Infer the image type from the file suffix. const typeMatch = srcKey.match(/\.([^.]*)$/); if (!typeMatch) { console.log("Could not determine the image type."); return; } // Check that the image type is supported const imageType = typeMatch[1].toLowerCase(); if (imageType != "jpg" && imageType != "png") { console.log(`Unsupported image type: ${imageType}`); return; } // Download the image from the S3 source bucket. try { const params = { Bucket: srcBucket, Key: srcKey }; var origimage = await s3.getObject(params).promise(); } catch (error) { console.log(error); return; } // set thumbnail width. Resize will set the height automatically to maintain aspect ratio. const width = 200; // Use the Sharp module to resize the image and save in a buffer. try { var buffer = await sharp(origimage.Body).resize(width).toBuffer(); } catch (error) { console.log(error); return; } // Upload the thumbnail image to the destination bucket try { const destparams = { Bucket: dstBucket, Key: dstKey, Body: buffer, ContentType: "image" }; const putResult = await s3.putObject(destparams).promise(); } catch (error) { console.log(error); return; } console.log('Successfully resized ' + srcBucket + '/' + srcKey + ' and uploaded to ' + dstBucket + '/' + dstKey); };
前述のコードを確認し、以下の点に注意します。
-
関数は、パラメータとして受信するイベントデータから、ソースバケット名とオブジェクトのキー名を知ることができます。オブジェクトが .jpg または .png の場合、コードではサムネイルが作成され、ターゲットバケットに保存されます。
-
コードでは、ターゲットバケットが存在し、ソースバケット名の後に文字列
-resized
を連結したものがそのバケット名になっているとします。たとえば、イベントデータで特定されたソースバケットがexamplebucket
の場合、コードではexamplebucket-resized
宛先バケットがあると想定されます。 -
作成されるサムネイルについて、コードでは、文字列
resized-
の後にソースオブジェクトキー名を連結したものをそのキー名として生成します。たとえば、ソースオブジェクトキーがsample.jpg
の場合、コードではキーresized-sample.jpg
があるサムネイルオブジェクトが作成されます。
デプロイパッケージは、Lambda 関数のコードと依存関係を含む .zip ファイルです。
デプロイパッケージを作成するには
-
Linux 環境でコマンドラインターミナルまたはシェルを開きます。ローカル環境の Node.js バージョンが関数の Node.js バージョンと一致していることを確認します。
-
lambda-s3
という名前のフォルダに関数コードindex.js
を保存します。 -
npm で Sharp ライブラリをインストールします。Linux の場合は、次のコマンドを使用します。
lambda-s3$
npm install sharp
macOS の場合は、次のコマンドを使用します。
lambda-s3$
npm install --arch=x64 --platform=linux --target=12.13.0 sharp
この手順を完了すると、以下のようなフォルダ構造になります。
lambda-s3 |- index.js |- /node_modules/sharp └ /node_modules/...
-
関数コードと依存関係を含むデプロイパッケージを作成します。
lambda-s3$
zip -r function.zip .
関数を作成するには
-
create-function
コマンドを使用して Lambda 関数を作成します。$
aws lambda create-function --function-name CreateThumbnail \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --timeout 10 --memory-size 1024 \ --role arn:aws:iam::
123456789012
:role/lambda-s3-role
AWS CLI バージョン 2 を使用している場合は、以下のコマンドパラメータを追加します。
--cli-binary-format raw-in-base64-out
role パラメータで、数値列を AWS アカウント ID に置き換えます。前の例のコマンドは、関数の設定として 10 秒のタイムアウト値を指定します。アップロードするオブジェクトのサイズに応じて、次の AWS CLI コマンドを使用してタイムアウトの値を増やす必要が生じる場合があります。
$
aws lambda update-function-configuration --function-name CreateThumbnail --timeout
30
Lambda 関数をテストする
このステップでは、サンプル Amazon S3 イベントデータを使用して、手動で Lambda 関数を呼び出します。
Lambda 関数をテストするには
-
以下の Amazon S3 サンプルイベントデータを
inputFile.txt
としてファイルに保存します。JSON を実際のsourcebucket
名と .jpg オブジェクトキーで更新する必要があります。{ "Records":[ { "eventVersion":"2.0", "eventSource":"aws:s3", "awsRegion":"us-west-2", "eventTime":"1970-01-01T00:00:00.000Z", "eventName":"ObjectCreated:Put", "userIdentity":{ "principalId":"AIDAJDPLRKLG7UEXAMPLE" }, "requestParameters":{ "sourceIPAddress":"127.0.0.1" }, "responseElements":{ "x-amz-request-id":"C3D13FE58DE4C810", "x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" }, "s3":{ "s3SchemaVersion":"1.0", "configurationId":"testConfigRule", "bucket":{ "name":"
sourcebucket
", "ownerIdentity":{ "principalId":"A3NL1KOZZKExample" }, "arn":"arn:aws:s3:::sourcebucket
" }, "object":{ "key":"HappyFace.jpg
", "size":1024, "eTag":"d41d8cd98f00b204e9800998ecf8427e", "versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko" } } } ] } -
次の Lambda CLI
invoke
コマンドを実行して関数を呼び出します。コマンドは非同期実行をリクエストします。オプションで、invocation-type
パラメータ値としてRequestResponse
を指定することで、このコマンドを同期的に呼び出すこともできます。$
aws lambda invoke --function-name CreateThumbnail --invocation-type Event \ --payload file://inputFile.txt outputfile.txt
-
ターゲットバケットでサムネイルが作成されたことを確認します。
Amazon S3 を設定してイベントを発行する
このステップでは、残りの設定を追加し、Amazon S3 がオブジェクト作成イベントを AWS Lambda に発行し、Lambda 関数を呼び出せるようにします。このステップでは、以下の作業を行います。
-
Lambda 関数のアクセスポリシーに、この関数の呼び出しを Amazon S3 に許可するアクセス権限を追加します。
-
通知設定をソースバケットに追加します。通知設定で、以下の項目を指定します。
-
Amazon S3 がイベントを発行するイベントタイプ。このチュートリアルでは、
s3:ObjectCreated:*
イベントタイプを指定し、オブジェクトが作成されたときに Amazon S3 がイベントを発行するようにします。 -
呼び出す Lambda 関数。
-
関数ポリシーにアクセス許可を追加するには
-
以下の Lambda CLI
add-permission
コマンドを実行して、Amazon S3 サービスプリンシパル(s3.amazonaws.com
)にlambda:InvokeFunction
アクションを実行するためのアクセス権限を付与します。次の条件を満たす場合にのみ関数を呼び出すアクセス権限が Amazon S3 に付与されることに注意してください。-
オブジェクト作成イベントが、特定のバケットで検出されます。
-
バケットはお客様のアカウントによって所有されています。バケットを削除すると、別のアカウントが同じ ARN でバケットを作成する可能性があります。
$
aws lambda add-permission --function-name CreateThumbnail --principal s3.amazonaws.com \ --statement-id s3invoke --action "lambda:InvokeFunction" \ --source-arn arn:aws:s3:::
sourcebucket
\ --source-accountaccount-id
-
-
AWS CLI
get-policy
コマンドを呼び出すことで、関数のアクセスポリシーを確認します。$
aws lambda get-policy --function-name CreateThumbnail
オブジェクト作成イベントを Lambda に発行するよう Amazon S3 にリクエストするため、ソースバケットで通知設定を追加します。
この手順では、オブジェクトがバケット内に作成されるたびに、関数を呼び出すようにバケットを設定します。このオプションはソースバケットでのみ設定し、トリガーされた関数からソースバケット内にオブジェクトを作成しないようにしてください。そうしないと、関数が関数自体をループ内で連続的に呼び出す可能性があります。
通知を設定するには
-
Amazon S3 コンソール
を開きます。 -
ソースバケットを選択します。
-
[Properties (プロパティ)] を選択します。
-
[Events (イベント)] で、以下の設定を使用して通知を設定します。
-
[Name (名前)] –
lambda-trigger
。 -
[Events (イベント)] –
All object create events
。 -
[Send to (送信先)] –
Lambda function
。 -
[Lambda] –
CreateThumbnail
。
-
イベント設定の詳細については、Amazon Simple Storage Service コンソールユーザーガイドの「イベント通知の有効化」を参照してください。
セットアップをテストする
これで、次のようにセットアップをテストできます。
-
Amazon S3 コンソールを使って、.jpg または .png オブジェクトをソースバケットにアップロードします。
-
CreateThumbnail
関数を使用してサムネイルがターゲットバケットに作成されたことを確認します。 -
CloudWatch コンソールでログを表示します。
リソースのクリーンアップ
このチュートリアル用に作成したリソースは、保持する必要がなければ、削除できます。使用しなくなった AWS リソースを削除することで、AWS アカウントに請求される不要な料金が発生しないようにできます。
Lambda 関数を削除するには
-
Lambda コンソールの [Functions (関数)
] ページを開きます。 -
作成した関数を選択します。
-
[ Actions] で、[Delete ] を選択します。
-
[削除] を選択します。
実行ロールを削除するには
-
IAM コンソールのロールページ
を開きます。 -
作成した実行ロールを選択します。
-
[ロールの削除] を選択します。
-
[はい、削除します] を選択します。
S3; バケットを削除するには
-
Amazon S3 コンソール
を開きます。 -
作成したソースバケットを選択します。
-
[削除] を選択します。
-
テキストボックスにソースバケットの名前を入力します。
-
[確認] を選択します。