話題の記事

[新ツール]AWS SAMをローカル環境で実行できるSAM Localがベータリリース

2017.08.16

この記事は公開されてから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を利用するので、環境に合わせて以下をインストールしておきましょう。

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公式でサポートというところがいいですね。色々捗りそうです。かなり素敵!!

参考