チュートリアル: Amazon S3 で AWS Lambda を使用する - AWS Lambda

チュートリアル: 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 サブシステムをインストールして、Windows 統合バージョンの Ubuntu および Bash を入手できます。

関数の依存関係を管理するには、npm をインストールします。

このチュートリアルでは、AWS CLI コマンドを使用して Lambda 関数を作成し、呼び出します。ASK CLI をインストールし、AWS 認証情報を使用して設定します

実行ロールを作成する

AWS リソースにアクセスするためのアクセス権限を関数に付与する実行ロールを作成します。

実行ロールを作成するには

  1. IAM コンソールの [Roles] ページを開きます。

  2. [ロールの作成] を選択します。

  3. 次のプロパティでロールを作成します。

    • [信頼されたエンティティ] – [AWS Lambda]。

    • [Permissions (アクセス許可)] – [AWSLambdaExecute]。

    • ロール名lambda-s3-role

AWSLambdaExecute ポリシーには、Amazon S3 でオブジェクトを管理してログを CloudWatch Logs に書き込むために関数が必要とするアクセス許可があります。

バケットを作成しサンプルオブジェクトをアップロードする

バケットを作成し、オブジェクトをアップロードするための手順を行います。

  1. Amazon S3 コンソールを開きます。

  2. バケットを 2 つ作成します。ターゲットバケット名は、source とその後に -resized を連結したものになる必要があります。ここで、source は、ソースに使用するバケットの名前です。たとえば、mybucketmybucket-resized です。

  3. ソースバケットで、.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 ファイルです。

デプロイパッケージを作成するには

  1. Linux 環境でコマンドラインターミナルまたはシェルを開きます。ローカル環境の Node.js バージョンが関数の Node.js バージョンと一致していることを確認します。

  2. lambda-s3 という名前のフォルダに関数コード index.js を保存します。

  3. 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/...
  4. 関数コードと依存関係を含むデプロイパッケージを作成します。

    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

role パラメータで、数値列を AWS アカウント ID に置き換えます。前の例のコマンドは、関数の設定として 10 秒のタイムアウト値を指定します。アップロードするオブジェクトのサイズに応じて、次の AWS CLI コマンドを使用してタイムアウトの値を増やす必要が生じる場合があります。

$ aws lambda update-function-configuration --function-name CreateThumbnail --timeout 30

Lambda 関数をテストする

このステップでは、サンプル Amazon S3 イベントデータを使用して、手動で Lambda 関数を呼び出します。

Lambda 関数をテストするには

  1. 以下の 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" } } } ] }
  2. 次の Lambda CLI invoke コマンドを実行して関数を呼び出します。コマンドは非同期実行をリクエストします。オプションで、invocation-type パラメータ値として RequestResponse を指定することで、このコマンドを同期的に呼び出すこともできます。

    $ aws lambda invoke --function-name CreateThumbnail --invocation-type Event \ --payload file://inputFile.txt outputfile.txt
  3. ターゲットバケットでサムネイルが作成されたことを確認します。

Amazon S3 を設定してイベントを発行する

このステップでは、残りの設定を追加し、Amazon S3 がオブジェクト作成イベントを AWS Lambda に発行し、Lambda 関数を呼び出せるようにします。このステップでは、以下の作業を行います。

  • Lambda 関数のアクセスポリシーに、この関数の呼び出しを Amazon S3 に許可するアクセス権限を追加します。

  • 通知設定をソースバケットに追加します。通知設定で、以下の項目を指定します。

    • Amazon S3 がイベントを発行するイベントタイプ。このチュートリアルでは、s3:ObjectCreated:* イベントタイプを指定し、オブジェクトが作成されたときに Amazon S3 がイベントを発行するようにします。

    • 呼び出す Lambda 関数。

関数ポリシーにアクセス許可を追加するには

  1. 以下の 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-account account-id
  2. AWS CLI get-policy コマンドを呼び出すことで、関数のアクセスポリシーを確認します。

    $ aws lambda get-policy --function-name CreateThumbnail

オブジェクト作成イベントを Lambda に発行するよう Amazon S3 にリクエストするため、ソースバケットで通知設定を追加します。

重要

この手順では、オブジェクトがバケット内に作成されるたびに、関数を呼び出すようにバケットを設定します。このオプションはソースバケットでのみ設定し、トリガーされた関数からソースバケット内にオブジェクトを作成しないようにしてください。そうしないと、関数が関数自体をループ内で連続的に呼び出す可能性があります。

通知を設定するには

  1. Amazon S3 コンソールを開きます。

  2. ソースバケットを選択します。

  3. [Properties (プロパティ)] を選択します。

  4. [Events (イベント)] で、以下の設定を使用して通知を設定します。

    • [Name (名前)] – lambda-trigger

    • [Events (イベント)] – All object create events

    • [Send to (送信先)] – Lambda function

    • [Lambda] – CreateThumbnail

イベント設定の詳細については、Amazon Simple Storage Service コンソールユーザーガイドの「イベント通知の有効化」を参照してください。

セットアップをテストする

これで、次のようにセットアップをテストできます。

  1. Amazon S3 コンソールを使って、.jpg または .png オブジェクトをソースバケットにアップロードします。

  2. CreateThumbnail 関数を使用してサムネイルがターゲットバケットに作成されたことを確認します。

  3. CloudWatch コンソールでログを表示します。