この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
コンニチハ、千葉です。
でました、その名もSAM Local !! ※2017/8/16時点でベータです
SAM Localとは?
AWS SAMを利用すると、サーバーレスアプリケーションをコードで定義しデプロイすることができます。
[新ツール] AWS Serverless Application Model (AWS SAM) を使ってサーバーレスアプリケーションを構築する
今回登場したAWS SAM Localを利用することで、AWSへデプロイする前にローカルでテストを実行できるようになります。
- AWS Lambda関数をローカルで実行しテストができる
- S3、DynamoDB、Kinesis、SNSなどの関す呼び出しをエミュレート
- ローカルのAPI Gatewayを起動し、ホットリロードによる開発が可能
- Lambda関数のインタラクティブなデバッグをサポート
すごくいいですね。ということで、早速さわってみました
やってみた
Dokcerのインストール
SAM LocalではDockerを利用するので、環境に合わせて以下をインストールしておきましょう。
- OSX: Docker for Mac
- Windows: Docker Toolbox
- Linux: Check your distro’s package manager (e.g. yum install docker)
SAM Localのインストール
NPMを利用しインストールできます。
$ npm install -g aws-sam-local
local$ sam --version
2017/08/15 23:17:58 0.1.0
sam version 0.1.0
Lambda関数をローカルで実行する
Lambdaをローカルで実行してみます!!Docker上で動くのでエミュレートではなくAWS上のLambdaに近い環境で動作確認できます。
テスト用に以下の3ファイルを用意します。
Lambda関数のコードです。
index.js
'use strict';
console.log('Loading function');
exports.handler = (event, context, callback) => {
callback(null, {
statusCode: 200,
headers: { "x-custom-header" : "my custom header value" },
body: "Hello " + event.body
});
}
SAMのテンプレートファイル。
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Simple CRUD webservice. State is stored in a SimpleTable (DynamoDB) resource.
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs4.3
Events:
GetResource:
Type: Api
Properties:
Path: /resource/{resourceId}
Method: put
Lambda実行時に渡すイベント
event.json
{"body": "chiba"}
ファイル一覧です。
local$ ls -l
total 24
-rw-r--r-- 1 chiba.jun staff 18 8 15 23:54 event.json
-rw-r--r-- 1 chiba.jun staff 143 8 15 23:57 index.js
-rw-r--r-- 1 chiba.jun staff 299 8 15 23:57 template.yaml
では、Lambda関数をローカル実行してみます。
local$ echo '{"body": "chiba"}' | sam local invoke HelloWorld
2017/08/16 01:24:54 0.1.0
2017/08/16 01:24:54 Successfully parsed template.yaml (version 2010-09-09)
2017/08/16 01:24:54 Connected to Docker 1.31
2017/08/16 01:24:54 Fetching lambci/lambda:nodejs4.3 image for nodejs4.3 runtime...
nodejs4.3: Pulling from lambci/lambda
Digest: sha256:39af2cb9aa8851d8b202e50b560472684e1671df7378b6a6d81dae2a4118a7e1
Status: Image is up to date for lambci/lambda:nodejs4.3
2017/08/16 01:24:57 Reading invoke payload from stdin (you can also pass it from file with --event)
2017/08/16 01:24:57 Invoking index.handler (nodejs4.3)
START RequestId: 7d5e9ba7-4b36-13d4-122d-fa6a2eaa042e Version: $LATEST
2017-08-15T16:24:58.008Z 7d5e9ba7-4b36-13d4-122d-fa6a2eaa042e Loading function
END RequestId: 7d5e9ba7-4b36-13d4-122d-fa6a2eaa042e
REPORT RequestId: 7d5e9ba7-4b36-13d4-122d-fa6a2eaa042e Duration: 11.25 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 23 MB
{"statusCode":200,"headers":{"x-custom-header":"my custom header value"},"body":"Hello chiba"}
Dockerイメージがダウンロードされ、Lambda関数が実行されました。
以下のようにも実行できます。
$ sam local invoke HelloWorld -e event.json
Lambdaファンクションをテストするときのペイロード
以下をトリガーにした時のペイロードを取得できます。
- S3
- Kinesis
- DynamoDB
- Cloudwatch Scheduled Event
- Cloudtrail
- API Gateway
例えば、S3をトリガーにしたLambdaファンクションのテストもローカルですぐ試すことができます。
$ sam local generate-event s3 --bucket <bucket> --key <key> | sam local invoke <function logical id>
実行してみます。
$ sam local generate-event s3
2017/08/16 00:37:10 0.1.0
{
"Records": [
{
"eventVersion": "2.0",
"eventTime": "1970-01-01T00:00:00.000Z",
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
・・・略
オプションでパラメータも指定できます。
local$ sam local generate-event s3 --help
2017/08/16 00:37:36 0.1.0
NAME:
sam local generate-event s3 - Generates a sample Amazon S3 event
USAGE:
sam local generate-event s3 [command options] [arguments...]
OPTIONS:
--region value, -r value The region the event should come from (default: "us-east-1")
--bucket value, -b value The S3 bucket the event should reference (default: "example-bucket")
--key value, -k value The S3 key the event should reference (default: "test/key")
API Gatewayのローカル実行
SAMのテンプレートを元に、ローカルにAPI Gateway環境を実行できます。ローカルでテストできるようになるのはかなり強力です。
API Gatewayを実行する前に構文チェックします。Valid!になれば有効です。
local$ sam validate
2017/08/15 22:41:11 0.1.0
Valid!
ではローカルでAPI Gatewayを実行してみましょう。
$ sam local start-api
リクエストを投げてみます。
local$ curl -H "Accept: application/json" -H "Content-type: application/json" \
-X PUT http://127.0.0.1:3000/resource/hoge \
-d 'chiba'
Hello chiba
ちゃんと動作しています!!ファイルを編集しながら、インタラクティブにテストできます。素敵。
今回はDynamoDBを使っていませんが、DynamoDB Localを利用すると、完全にローカル環境で開発できるようになりますね。
AWSへのデプロイ
ローカルで動作確認できたので、AWSへデプロイします。
$ sam package --template-file template.yaml --s3-bucket [SAM用のバケット] --output-template-file package.yaml
$ sam deploy --template-file package.yaml --stack-name SAM-Sample --capabilities CAPABILITY_IAM
環境が構成されたので接続してみます。
curl -H "Accept: application/json" -H "Content-type: application/json" \
-X PUT https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/resource/hoge \
-d chiba
Hello chiba
ちゃんとデプロイされています!!
最後に
SAMで定義したアプリケーションをローカルでテストし、そのままAWS環境へデプロイできるようになります。AWS上に開発環境を用意するとデプロイに時間がかかり、インタラクティブなテストが難しかったですが、ローカルでも実行できるようになりました。AWS公式でサポートというところがいいですね。色々捗りそうです。かなり素敵!!