
AWS Cloud9からSAM Localをためしてみる #serverless #adventcalendar #reinvent
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも!大阪オフィスの西村祐二です。
このエントリはServerless Advent Calendar 2017の21日目の記事となります。
AWS Cloud9を利用する際に、EC2上に新しく構築するとAWS Cloud9用のAMIを使用してインスタンスが作成されます。 このAMIにはSAM Localがデフォルトでインストールされているので今回こちらをためしたいと思います。
AWS Cloud9の環境構築
下記ブログがとても参考になります。 本ブログではすでにAWS Cloud9のIDEが利用できることを前提にすすめてまいります。
AWS Cloud9のIDEで提供されるターミナルで作業していきます。
SAM Localをためしてみる
SAM Localについては下記ブログを参考にします。
確認
SAM Local が入っているか確認します。 コマンドで確認するときちんと入っているようですね。
0.2.2
が入っているようですね。
最新版があるようなのであげておきましょう。
$ npm update -g aws-sam-local
> aws-sam-local@0.2.2 preuninstall /home/ec2-user/.nvm/versions/node/v6.11.4/lib/node_modules/aws-sam-local
> go-npm uninstall
> aws-sam-local@0.2.4 postinstall /home/ec2-user/.nvm/versions/node/v6.11.4/lib/node_modules/aws-sam-local
> go-npm install
Downloading from URL: https://github.com/awslabs/aws-sam-local/releases/download/v0.2.4/sam_0.2.4_linux_amd64.tar.gz
+ aws-sam-local@0.2.4
updated 3 packages in 3.25s
$ sam --version
sam version 0.2.4
これで最新版になりました。
テスト用のファイルを用意
SAMのテンプレートファイルを作成します。 今回は「python3.6」としています。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Local test
Resources:
HelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: python3.6
Events:
GetResource:
Type: Api
Properties:
Path: /resource/{resourceId}
Method: put
Lambda実行時に渡すeventファイルを作成します。
{
"body": "Hello World SAM Local"
}
Lambda関数のコードを作成します。
import json
print('Loading function')
def handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
return {'statusCode': 200,
'body': "Hello " + json.dumps(event['body']),
'headers': {'Content-Type': 'application/json'}}
構文確認
SAM Localで構文確認をします。 Valid!となればokのようです。
$ sam validate
Valid!
動作確認
テスト用のファイルが用意できたら AWS Cloud9上のSAM LocalでLambdaを実行してみましょう。
$ sam local invoke HelloWorld -e event.json
2017/12/20 07:50:24 Successfully parsed template.yaml
2017/12/20 07:50:24 Connected to Docker 1.27
2017/12/20 07:50:24 Fetching lambci/lambda:python3.6 image for python3.6 runtime...
python3.6: Pulling from lambci/lambda
Digest: sha256:
Status: Image is up to date for lambci/lambda:python3.6
2017/12/20 07:50:24 Invoking index.handler (python3.6)
2017/12/20 07:50:24 Mounting /home/ec2-user/environment as /var/task:ro inside runtime container
START RequestId: Version: $LATEST
Loading function
Received event: {
"body": "Hello World SAM Local"
}
END RequestId:
REPORT RequestId: Duration: 0 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 18 MB
{"statusCode": 200, "body": "Hello \"Hello World SAM Local\"", "headers": {"Content-Type": "application/json"}}
作成したプログラム通りに実行されていますね。
トリガー連携のテスト
SAM LocalではLambdaを実行するための トリガーを想定したペイロードが取得できます。
下記はAPI Gatewayをトリガーとした際のeventファイルの出力です。
$ sam local generate-event api --resource /resource
{
"body": "{ \"test\": \"body\"}",
"resource": "/resource",
"requestContext": {
"resourceId": "123456",
"apiId": "1234567890",
"resourcePath": "/resource",
"httpMethod": "POST",
.
.
.
オプションでパラメータを変更することが可能です。
$ sam local generate-event api --help
NAME:
sam local generate-event api - Generates a sample Amazon API Gateway event
USAGE:
sam local generate-event api [command options] [arguments...]
OPTIONS:
--method value, -m value HTTP method (default: "POST")
--body value, -b value HTTP body (default: "{ \\\"test\\\": \\\"body\\\"}")
--resource value, -r value API Gateway resource name (default: "/{proxy+}")
--path value, -p value HTTP path (default: "/examplepath")
実行はパイプでわたすだけいいので簡単ですね。
$ sam local generate-event api | sam local invoke <logical ID>
API Gatewayのテストをやってみる
SAMのテンプレートをもとに、AWS Cloud9上のSAM Localを使ってAPI Gatewayのテスト実行ができます。 かなり強力です。
下記コマンドで、API サーバを立ててくれます。
$ sam local start-api
2017/12/20 06:43:09 Connected to Docker 1.27
2017/12/20 06:43:09 Fetching lambci/lambda:python3.6 image for python3.6 runtime...
python3.6: Pulling from lambci/lambda
Digest: sha256:
Status: Image is up to date for lambci/lambda:python3.6
Mounting index.handler (python3.6) at http://127.0.0.1:3000/resource/{resourceId} [PUT]
You can now browse to the above endpoints to invoke your functions.
You do not need to restart/reload SAM CLI while working on your functions,
changes will be reflected instantly/automatically. You only need to restart
SAM CLI if you update your AWS SAM template.
上記、実行ログより、 http://127.0.0.1:3000/resource/{resourceId}
に対して、リクエストして動作確認をしてみましょう。 新しくターミナルを開き、そこから下記コマンドを実行してみます。
$ curl -H "Accept: application/json" -H "Content-type: application/json" \
-X PUT http://127.0.0.1:3000/resource/hoge \
-d 'sam local'
Hello "sam local"
きちんとレスポンスのbody部分がかえってきていることがわかります。
SAM LocalでたてたAPI サーバー側のログは下記のようになってました。
2017/12/20 08:04:05 Invoking index.handler (python3.6)
2017/12/20 08:04:05 Mounting /home/ec2-user/environment as /var/task:ro inside runtime container
START RequestId: Version: $LATEST
Loading function
Received event: {
"httpMethod": "PUT",
"body": "sam local",
"resource": "/resource/hoge",
"requestContext": {
"resourcePath": "/resource/hoge",
"httpMethod": "PUT",
"stage": "prod",
"identity": {
"sourceIp": "127.0.0.1:54768"
}
},
"queryStringParameters": {},
"headers": {
"Accept": "application/json",
"Content-Length": "9",
"Content-Type": "application/json",
"User-Agent": "curl/7.53.1"
},
"pathParameters": {
"resourceId": "hoge"
},
"stageVariables": null,
"path": "/resource/hoge"
}
END RequestId:
REPORT RequestId: Duration: 0 ms Billed Duration: 0 ms Memory Size: 0 MB Max Memory Used: 19 MB
Lambdaのコードを修正しても、再起動せずに更新してくれるので大変便利です。
さいごに
いかがだったでしょうか。
AWS Cloud9からSAM Localをためしてみました。 特に問題なく利用できました。
環境構築せずに、SAM Localを利用できるのでとても便利ですね。 AWS Cloud9上からLambda開発がはかどりそうです。
誰かの参考になれば幸いです。