- 追加された行はこの色です。
- 削除された行はこの色です。
[[AWSメモ]] >
* AWS Lambda のローカル開発手順 [#tb98f5c9]
#setlinebreak(on);
#contents
-- 参考URL
--- http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/test-sam-local.html
--- https://aws.amazon.com/jp/blogs/news/new-aws-sam-local-beta-build-and-test-serverless-applications-locally/
** 事前準備 [#c2fe10a0]
#html(<div style="padding-left:20px;">)
aws-sdk と AWS CLI をインストールしておく。
[[AWSローカル開発環境の構築]] を参照
#html(</div>)
** SAM Local のインストール [#ve75d1ce]
#html(<div style="padding-left:20px;">)
#myterm2(){{
# NPMでインストール
npm install -g aws-sam-local
# インストール(バージョン)確認
sam --version
}}
#html(</div>)
** Dockerのインストール [#ua6e3fad]
#html(<div style="padding-left:20px;">)
「SAM Local は docker-lambda というカスタマイズされた Docker イメージを自動的に提供します」という事らしい。
http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html
インストールガイドに従ってインストール
https://docs.docker.com/engine/installation/
#html(</div>)
** DynamoDB ローカルのインストール [#oc49f3aa]
#html(<div style="padding-left:20px;">)
参考)
http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html
https://s3.ap-south-1.amazonaws.com/dynamodb-local-mumbai/dynamodb_local_latest.zip からダウンロード、解凍する。
DymanoDBの開始
#myterm2(){{
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
}}
※デフォルトでは localhost:8000 で動作する。
※AWS CLI で エンドポイント指定するか、http://localhost:8000/shell から各種操作が可能。
#html(</div>)
** ローカルIPアドレスの確認 [#xf96ff89]
#html(<div style="padding-left:20px;">)
上記で起動した DynamoDB はホストOS上の 8000ポートで動作しているが、
sam local は docker上で動作する為、sam local から ローカルへの DynamoDB には
localhost:8000 という指定ではアクセスはできない。
なので、ローカルホストの IPアドレスを確認し、lo0 に 127.0.0.1 (localhost) 以外のアドレスが割り当たっていない場合は、以下の通り割り当てる。
#myterm2(){{
sudo ifconfig lo0 alias 10.20.30.40/24
}}
#html(<span>※10.20.30.40/24 は 割り当てる IPアドレスとサブネットマスク</span>)
#html(</div>)
** SAM localの 主なCLI オペレーション [#f99d3fa8]
#html(<div style="padding-left:20px;">)
|コマンド|説明|補足|h
|start-api|すべての Lambda 関数をホストするローカル HTTP サーバーを作成する。||
|invoke|ローカル Lambda 関数を一度呼び出し、呼び出しの完了後に終了する。||
|generate-event|疑似サーバーレスイベントを生成する。||
|validate|テンプレートを検証する。||
|package および deploy|AM アプリケーションのパッケージングおよびデプロイメントを行う|http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/serverless-deploy-wt.html#serverless-deploy|
#html(</div>)
** SAM Local によるシンプルなアプリケーションの構築 [#y6b906ae]
#html(<div style="padding-left:10px;">)
参考
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/test-sam-local.html#sam-cli-simple-app
#html(</div>)
*** Lambda関数の作成 [#s4cc70b1]
#html(<div style="padding-left:20px;">)
#TODO(handler を分けた方が良さそう)
https://github.com/awslabs/serverless-application-model/tree/master/examples/2016-10-31/api_backend
book.js
#mycode2(){{
'use strict';
var AWS = require('aws-sdk');
var dynamoOpt = {apiVersion: '2012-08-10'};
if (process.env.DYNAMO_REGION && process.env.DYNAMO_END_POINT) {
dynamoOpt.region = process.env.DYNAMO_REGION;
dynamoOpt.endpoint = process.env.DYNAMO_END_POINT;
}
var documentClient = new AWS.DynamoDB.DocumentClient(dynamoOpt);
const createResponse = (callback, statusCode, body) => {
var res = {
"statusCode": statusCode,
"body": JSON.stringify(body)
}
callback(null, res);
}
exports.handler = (event, context, callback) => {
var req = event.body || event;
if (typeof(req) === "string" && req !== "") {
req = JSON.parse(req);
}
var id = false;
if (event.pathParameters){
id = event.pathParameters.id || false;
}
switch(event.httpMethod){
case "GET":
if(id && id > 0) {
var params = {
TableName : 'Books',
FilterExpression : 'id = :id',
ExpressionAttributeValues : {':id' : id }
};
documentClient.scan(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "Get Error!", "err": err});
} else {
createResponse(callback, 200, data);
console.log(data);
}
});
return;
} else {
var params = {
TableName : 'Books'
};
documentClient.scan(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "List Error!", "err": err});
} else {
createResponse(callback, 200, data);
console.log(data);
}
});
}
break;
case "POST":
var params = {
TableName : 'Books',
Item: {
"id" : req.id,
"isbn" : req.isbn,
"title" : req.title,
"price" : parseInt(req.price,10)
}
};
documentClient.put(params, function(err, data) {
if (err) {
console.log(err);
createResponse(callback, 500, { "msg": "Create Error!", "err": err, "req": req});
} else {
createResponse(callback, 200, { "msg": "Create OK!"});
}
});
break;
case "PUT":
var params = {
TableName : 'Books',
Key: { "id" : id },
ExpressionAttributeNames: {
"#isbn" : "isbn",
"#title" : "title",
"#price" : "price"
},
ExpressionAttributeValues: {
":isbn" : req.isbn,
":title" : req.title,
":price" : parseInt(req.price, 10)
},
UpdateExpression: "SET #isbn = :isbn, #title = :title, #price = :price"
};
documentClient.update(params, function(err, data) {
if (err) {
console.log(err);
console.log(data);
createResponse(callback, 500, { "msg": "Update Error!", "err": err});
} else {
createResponse(callback, 200, { "msg": "Update OK!"});
}
});
break;
case "DELETE":
var params = {
TableName : 'Books',
Key: { "id" : id }
};
documentClient.delete(params, function(err, data) {
if (err) {
console.log(err);
console.log(data);
createResponse(callback, 500, { "msg": "Delete Error!", "err": err});
} else {
createResponse(callback, 200, { "msg": "Delete OK!"});
}
});
break;
default:
console.log("Error: unsupported HTTP method (" + event.httpMethod + ")");
createResponse(callback, 501, { "msg": "Error: unsupported HTTP method (" + event.httpMethod + ")" } );
}
}
}}
#html(</div>)
*** テンプレートの作成 [#d025e069]
#html(<div style="padding-left:20px;">)
template-local.yml
#mycode2(){{
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Test serverless application.
Resources:
BookFunction:
Type: AWS::Serverless::Function
Properties:
Handler: book.handler
Runtime: nodejs6.10
Environment:
Variables:
DYNAMO_END_POINT: http://10.20.30.40:8000 #上記で確認/設定したローカルのIPアドレス
DYNAMO_REGION: localhost
Events:
List:
Type: Api
Properties:
Path: /book
Method: get
Create:
Type: Api
Properties:
Path: /book
Method: post
Update:
Type: Api
Properties:
Path: /book/{id}
Method: put
Delete:
Type: Api
Properties:
Path: /book/{id}
Method: delete
}}
#html(</div>)
*** APIサーバー開始 [#w5014e32]
#html(<div style="padding-left:20px;">)
#myterm2(){{
sam local start-api --template template-local.yml
}}
#html(</div>)
*** 動作確認 [#oad393b7]
#html(<div style="padding-left:20px;">)
一覧
#myterm2(){{
curl -v http://localhost:3000/book
}}
登録
#myterm2(){{
curl -v -XPOST --data '{ "id" : "A01", "isbn" : "ABC001", "title" : "テスト001", "price": 1008 }' http://localhost:3000/book
}}
キー指定検索
#myterm2(){{
curl -v http://localhost:3000/book/A01
}}
更新(キー指定)
#myterm2(){{
curl -v -XPUT --data '{ "id" : "A01", "isbn" : "ABC001", "title" : "テスト001", "price": 2016 }' http://localhost:3000/book/A01
}}
削除(キー指定)
#myterm2(){{
curl -v -XDELETE http://localhost:3000/book/A01
}}
#html(</div>)
** パッケージ化とデプロイ [#idc328e9]
#TODO
** サンプル/参考URL [#j3d6d130]
#html(<div style="padding-left:20px;">)
*** aws-sdk から DynamoDB を利用するサンプル [#cba97dbc]
http://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/dynamodb-examples.html
*** aws-sdk から Lambda を利用するサンプル [#cb542160]
http://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/lambda-examples.html
*** AWS SAM Local(ベータ版) – サーバーレスアプリケーションをローカルに構築してテストする [#b988ed40]
https://aws.amazon.com/jp/blogs/news/new-aws-sam-local-beta-build-and-test-serverless-applications-locally/
*** SAM ローカルを使用してサーバーレスアプリケーションをローカルでテストする [#df541c69]
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/test-sam-local.html
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/test-sam-local.html#sam-cli-simple-app
*** Lambda ベースのアプリケーションをデプロイする [#o0c6a710]
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/deploying-lambda-apps.html
*** 独自のサーバーレスアプリケーションを作成する(パッケージ化とデプロイ) [#k6fc6af3]
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/serverless-deploy-wt.html
*** Lambda ベースのアプリケーションのデプロイメントを自動化する [#x244e615]
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/automating-deployment.html
#html(</div>)