メニュー
AWS Lambda
開発者ガイド

SAM ローカルを使用してサーバーレスアプリケーションをローカルでテストする

この機能は、パブリックベータの一部として提供されており、随時変更される場合があります。

前述したように、AWS SAM はサーバーレスアプリケーションを迅速かつ簡単にデプロイする方法です。これにより、シンプルなテンプレートを記述して関数およびイベントソース (Amazon API Gateway、Amazon S3、Kinesis など) を定義できます。SAM Local は、AWS SAM に基づく AWS CLI ツールであり、サーバーレスアプリケーションを Lambda ランタイムにアップロードする前にローカルで開発、テスト、および分析するための環境を提供します。SAM Local では、Linux、Mac、または Microsoft Windows を問わず、AWS ランタイム環境をシミュレートするローカルテスト環境を作成できます。これにより、パフォーマンスなどの問題に対処しやすくなります。SAM Local を使用すると、アプリケーションパッケージを AWS Lambda ランタイムに再デプロイする必要がないため、Lambda 関数コードをより高速に反復開発できます。詳細については、「SAM Local によるシンプルなアプリケーションの構築」を参照してください。

SAM Local は、AWS SAM と連携するため、SAM テンプレートで定義された関数を直接呼び出すことも、API ゲートウェイ エンドポイント経由で呼び出すこともできます。SAM Local の機能を使用して、独自のテスト環境でサーバーレスアプリケーションのパフォーマンスを分析し、必要に応じて更新できます。以下の例では、SAM Local を使用するその他の利点をサンプルオペレーションコードで示します。たとえば、次の操作を実行できます。

  • サンプルの関数ペイロード (Amazon S3 イベントなど) を生成する。

    Copy
    $ sam local generate-event s3 --bucket bucket-name --key key-name > event_file.json
  • Lambda 関数を使用してサンプルの関数ペイロードをローカルでテストする。

    Copy
    $ sam local invoke function-name -e event_file.json
  • ローカルの API ゲートウェイ を生成して HTTP リクエストおよびレスポンスの機能をテストする。ホットリロード機能を使用することで、関数を再起動したり AWS ランタイムにリロードしたりせずにテストおよび反復実行できます。

    Copy
    $ sam local start-api

    SAM Local によって、SAM テンプレート内に API イベントソースが定義されている関数があれば自動的に検出され、定義された HTTP パスにマウントされます。次の例では、Ratings 関数が GET リクエストによって ratings.py:handler() /ratings にマウントします。

    Copy
    Ratings: Type: AWS::Serverless::Function Properties: Handler: ratings.handler Runtime: python3.6 Events: Api: Type: Api Properties: Path: /ratings Method: get

    デフォルトでは、SAM Local は Proxy との統合を使用して、Lambda 関数からのレスポンスに statusCodeheadersbody のいずれかが含まれるようにします。(例:

    Copy
    // Example of a Proxy Integration response exports.handler = (event, context, callback) => { callback(null, { statusCode: 200, headers: { "x-custom-header" : "my custom header value" }, body: "hello world" }); }

    Lambda 関数が有効な プロキシ統合レスポンスを返さない場合、関数にアクセスすると HTTP 500 (Internal Server Error) レスポンスが返されます。また、SAM Local は次のエラーログメッセージを表示するため、問題の診断に役立ちます。

    Copy
    ERROR: Function ExampleFunction returned an invalid response (must include one of: body, headers or statusCode in the response object)
  • メモリの最大使用量や Lambda 関数呼び出しのタイムアウト制限などのラインタイム制約を遵守していることを確認する。

  • AWS Lambda ランタイムログ、および Lambda 関数コード (console.log など) で指定されたカスタマイズされたログ出力を検査する。SAM Local では、この出力が自動的に表示されます。例を以下に示します。

    Copy
    START RequestId: 2137da9a-c79c-1d43-5716-406b4e6b5c0a Version: $LATEST 2017-05-18T13:18:57.852Z 2137da9a-c79c-1d43-5716-406b4e6b5c0a Error: any error information END RequestId: 2137da9a-c79c-1d43-5716-406b4e6b5c0a REPORT RequestId: 2137da9a-c79c-1d43-5716-406b4e6b5c0a Duration: 12.78 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 29 MB
  • AWS CLI で確定したセキュリティ認証情報を受け入れる。これにより、サーバーレスアプリケーションを構成している AWS のサービスを Lambda 関数でリモートから呼び出すことができます。AWS CLI をまだインストールしていない場合は、「AWS コマンドラインインターフェイスのインストール」を参照してください。

    AWS CLI および SDK と同様に、SAM Local は次の順序で認証情報を検索します。

    • 環境変数 (AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)

    • AWS 認証情報ファイル (Linux、MacOS、Unix の ~/.aws/credentials、または Windows の C:\Users\USERNAME \.aws\credentials)

    • インスタンスプロファイル認証情報 (割り当てられたインスタンスロールで Amazon EC2 を実行している場合)

ランタイムのサポート

SAM Local は以下の AWS ランタイムをサポートします。

  • node.js 4.3

  • node.js 6.10

  • python 2.7

  • python 3.6

  • java8

SAM Local の使用条件

SAM Local を使用するには、Docker と SAM Local をインストールする必要があります。

Docker のインストール

Docker は、Linux、Mac、Windows を問わず、アプリケーションを構築、管理、テストできるオープンソースソフトウェアコンテナプラットフォームです。詳細およびダウンロード手順については、「Docker」を参照してください。

Docker をインストールすると、SAM Local は docker-lambda というカスタマイズされた Docker イメージを自動的に提供します。このイメージは、AWS パートナーによるライブ AWS Lambda 実行環境のシミュレーション専用に設計されています。この環境には、インストール済みのソフトウェア、ライブラリ、セキュリティのアクセス許可、環境変数、および Lambda 実行環境と利用できるライブラリ で説明されているその他の機能が含まれます。

docker-lambda を使用して、Lambda 関数をローカルで呼び出すことができます。この環境では、AWS Lambda ランタイムを再デプロイしなくても、このランタイムと同じようにサーバーレスアプリケーションが実行および動作します。この環境での実行と動作には、タイムアウトやメモリ使用量などの検討事項が反映されます。

重要

これはシミュレートされた環境であるため、ローカルのテスト結果が実際の AWS ランタイムの結果と正確に一致する保証はありません。

詳細については、GitHubDocker Lambda を参照してください。(Github アカウントをお持ちでない場合は無料で作成できます。その後 Docker Lambda にアクセスしてください。)

SAM Local のインストール

SAM Local は、Linux、Mac、および Windows 環境で実行できます。SAM Local を最も簡単にインストールするには NPM を使用します。

Copy
npm install -g aws-sam-local

次に、インストールが正常に完了したことを確認します。

Copy
sam --version

NPM が適切に機能しない場合は、最新のバイナリをダウンロードして SAM Local の使用をすぐに開始できます。バイナリは、SAM CLI GitHub Repository の「Releases」セクションにあります。

SAM Local の使用開始

SAM Local は、以下の CLI オペレーションで構成されています。

  • start-api: すべての Lambda 関数をホストするローカル HTTP サーバーを作成します。ブラウザまたは CLI を使用してアクセスすると、このオペレーションは Docker コンテナをローカルで起動して関数を呼び出します。AWS::Serverless::Function リソースの CodeUri プロパティを読み取り、Lambda 関数コードが含まれているファイルシステムのパスを見つけます。このパスは、プロジェクトのルートディレクトリ (Node.js や Python などの解釈された言語の場合)、コンパイル済みアーティファクトを保存するビルドディレクトリ、または .jar ファイル (Java の場合) です。

    解釈された言語を使用する場合、ローカルな変更は同じ Docker コンテナ内で使用可能になります。このアプローチでは、再デプロイすることなく、Lambda 関数の再呼び出しが可能です。複雑なパッキングサポートを必要とするコンパイル済み言語またはプロジェクトでは、独自のビルドソリューションを実行し、必要なビルドの依存関係ファイルがあるディレクトリを AWS SAM で参照することをお勧めします。

  • invoke: ローカル Lambda 関数を一度呼び出し、呼び出しの完了後に終了します。

    Copy
    # Invoking function with event file $ sam local invoke "Ratings" -e event.json # Invoking function with event via stdin $ echo '{"message": "Hey, are you there?" }' | sam local invoke "Ratings" # For more options $ sam local invoke --help
  • generate-event: 疑似サーバーレスイベントを生成します。これらを使用して、Amazon S3、Kinesis、DynamoDB などの非同期イベントに応答する関数をローカルで開発およびテストできます。generate-event オペレーションで使用できるコマンドオプションを以下に示します。

    Copy
    sam local generate-event NAME: sam local generate-event - Generates Lambda events (e.g. for S3/Kinesis etc) that can be piped to 'sam local invoke' USAGE: sam local generate-event command [command options] [arguments...] COMMANDS: s3 Generates a sample Amazon S3 event sns Generates a sample Amazon SNS event kinesis Generates a sample Amazon Kinesis event dynamodb Generates a sample Amazon DynamoDB event api Generates a sample Amazon API Gateway event schedule Generates a sample scheduled event OPTIONS: --help, -h show help
  • validate: 正式な AWS Serverless Application Model 仕様に照らしてテンプレートを検証します。次に例を示します。

    Copy
    $ sam validate ERROR: Resource "HelloWorld", property "Runtime": Invalid value node. Valid values are "nodejs4.3", "nodejs6.10", "java8", "python2.7", "python3.6"(line: 11; col: 6) # Let's fix that error... $ sed -i 's/node/nodejs6.10/g' template.yaml $ sam validate Valid!
  • package および deploy: sam package および sam deploy は、AWS CloudFormation の package コマンドおよび deploy コマンドを暗黙で呼び出します。SAM アプリケーションのパッケージングおよびデプロイメントの詳細については、「パッケージ化とデプロイ」を参照してください。

    SAM Local で package コマンドおよび deploy コマンドを使用する方法は以下のとおりです。

    Copy
    # Package SAM template $ sam package --template-file sam.yaml --s3-bucket mybucket --output-template-file packaged.yaml # Deploy packaged SAM template $ sam deploy --template-file ./packaged.yaml --stack-name mystack --capabilities CAPABILITY_IAM

SAM Local によるシンプルなアプリケーションの構築

製品リストの作成、読み取り、更新、および削除を行うシンプルな RESTful API オペレーションを構築するとします。この場合、まず次のディレクトリ構造を作成します。

dir/products.js

dir/template.yaml

template.yaml ファイルは、Lambda 関数を記述する AWS SAM テンプレートです。この関数 1 つで、すべての API リクエストを処理します。

注記

デフォルトでは、start-api コマンドおよび invoke コマンドは template.yaml ファイルを作業ディレクトリで探します。別のディレクトリの template.yaml ファイルを参照する場合は、これらのオペレーションに -t パラメータまたは --template パラメータを追加して、このファイルへの絶対パスまたは相対パスを渡します。

template.yaml ファイルに以下の内容をコピーして貼り付けます。

Copy
AWSTemplateFormatVersion : '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: My first serverless application. Resources: Products: Type: AWS::Serverless::Function Properties: Handler: products.handler Runtime: nodejs6.10 Events: ListProducts: Type: Api Properties: Path: /products Method: get CreateProduct: Type: Api Properties: Path: /products Method: post Product: Type: Api Properties: Path: /products/{product} Method: any

前の例では、以下の RESTful API エンドポイントを設定します。

  • /products への PUT リクエストで新しい製品を作成します。

  • /products への GET リクエストですべての製品を一覧表示します。

  • /products/{product} への GETPUT、または DELETE リクエストで製品の読み取り、更新、または削除を行います。

次に、以下のコードをコピーして products.js ファイル内に貼り付けます。

Copy
'use strict'; exports.handler = (event, context, callback) => { let id = event.pathParameters.product || false; switch(event.httpMethod){ case "GET": if(id) { callback(null, {body: "This is a READ operation on product ID " + id}); return; } callback(null, {body: "This is a LIST operation, return all products"}); break; case "POST": callback(null, {body: "This is a CREATE operation"}); break; case "PUT": callback(null, {body: "This is an UPDATE operation on product ID " + id}); break; case "DELETE": callback(null, {body:"This is a DELETE operation on product ID " + id}); break; default: // Send HTTP 501: Not Implemented console.log("Error: unsupported HTTP method (" + event.httpMethod + ")"); callback(null, { statusCode: 501 }) } }

start-api コマンドを呼び出して API オペレーションのローカルコピーを起動します。

Copy
$ sam local start-api 2017/05/18 14:03:01 Successfully parsed template.yaml (AWS::Serverless-2016-10-31) 2017/05/18 14:03:01 Found 1 AWS::Serverless::Function 2017/05/18 14:03:01 Mounting products.handler (nodejs6.10) at /products [POST] 2017/05/18 14:03:01 Mounting products.handler (nodejs6.10) at /products/{product} [OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT] 2017/05/18 14:03:01 Mounting products.handler (nodejs6.10) at /products [GET] 2017/05/18 14:03:01 Listening on http://localhost:3000 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload while working on your functions, changes will be reflected instantly/automatically. You only need to restart if you update your AWS SAM template.

次に、ブラウザまたは CLI を使用して API エンドポイントをローカルでテストできます。

Copy
$ curl http://localhost:3000/products "This is a LIST operation, return all products" $ curl -XDELETE http://localhost:3000/products/1 "This is a DELETE operation on product ID 1"

その他のサンプルを確認するには、aws sam local/samples を参照してください。

ローカルなログ記録

invoke コマンドおよび start-api コマンドを使用して、Lambda 関数の呼び出しのログをファイルにパイプできます。このアプローチは、SAM Local に対して自動テストを実行し、分析用のログを取得する場合に便利です。次に例を示します。

Copy
$ sam local invoke --log-file ./output.log

環境変数ファイルの使用

Lambda 関数で Environment Variables を使用すると、SAM Local は invoke コマンドと start-api コマンドの両方に --env-vars 引数を渡します。この引数では、関数に定義されている環境変数の値がある JSON ファイルを使用できます。JSON ファイルの構造は次のようになります。

Copy
{ "MyFunction1": { "TABLE_NAME": "localtable", "BUCKET_NAME": "testBucket" }, "MyFunction2": { "TABLE_NAME": "localtable", "STAGE": "dev" }, }

次に、以下のコマンドを使用して JSON ファイルにアクセスします。

Copy
$ sam local start-api --env-vars env.json

シェル環境の使用

シェル環境で定義された変数は、Lambda 関数の変数にマッピングされると、Docker コンテナに渡されます。シェル変数は関数からグローバルにアクセスできます。たとえば、2 つの関数として MyFunction1 および MyFunction2 があり、どちらにも TABLE_NAME という変数があるとします。この場合、シェル環境を通じて提供される TABLE_NAME の値は両方の関数で使用できます。

次のコマンドは、両方の関数で TABLE_NAME の値を myTable に設定します。

Copy
$ TABLE_NAME=mytable sam local start-api

注記

柔軟性を増すために、シェル変数と組み合わせて環境変数を保持する外部 JSON ファイルを使用できます。変数が両方の場所に定義されている場合、外部ファイルの変数によってシェルバージョンが上書きされます。以下は優先順位 (最高から最低) です。

  • 環境変数ファイル

  • シェル環境

  • SAM テンプレート内のハードコードされた値

SAM Local でのデバッグ

sam local invoke および sam local start-api は、いずれも関数のローカルデバッグをサポートします。デバッグサポートを有効にして SAM Local を実行するには、コマンドラインで --debug-port または -d を指定します。

Copy
# Invoke a function locally in debug mode on port 5858 $ sam local invoke -d 5858 function logical id # Start local API Gateway in debug mode on port 5858 $ sam local start-api -d 5858

注記

sam local start-api を使用する場合、ローカル API Gateway はすべての Lambda 関数を公開します。ただし、指定できるデバッグポートは 1 つのみであるため、一度に 1 つの関数のみデバッグできます。

Python で記述された関数のデバッグ

Node.js や Java とは異なり、Python では Lambda 関数コードでリモートデバッグを有効にする必要があります。Python ランタイム (2.7 または 3.6) のいずれかを使用する関数に対して (上述の --debug-port オプションまたは -d オプションを使用して) デバッグを有効にすると、SAM Local はそのポートを通じてホストマシンから Lambda コンテナへのマッピングを行います。リモートデバッグを有効にするには、remote-pdb などの Python パッケージを使用します。

重要

ホストの設定時に、デバッガーはコードでリスンするため、127.0.0.1 ではなく 0.0.0.0 を必ず使用します。