1.ストリームを有効にしたdynamoDBテーブルを作成する
テーブル名:dynamodbtesttable
パーティションキー:Username
ソートキー:Timestamp
ストリーム:有効、トリームに書き込まれる情報を項目の新しいイメージと古いイメージの両方(NEW_AND_OLD_IMAGES)にしました。
StreamViewType | |
---|---|
StreamViewType | テーブル内のデータが変更されるたびにストリームに書き込まれる情報を指定します。 |
KEYS_ONLY | 変更された項目のキー属性のみ。 |
NEW_IMAGE | 変更後に表示される項目全体。 |
OLD_IMAGE | 変更前に表示されていた項目全体。 |
NEW_AND_OLD_IMAGES | 項目の新しいイメージと古いイメージの両方。 |
aws dynamodb create-table \
--table-name dynamodbtesttable \
--attribute-definitions AttributeName=Username,AttributeType=S AttributeName=Timestamp,AttributeType=S \
--key-schema AttributeName=Username,KeyType=HASH AttributeName=Timestamp,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
出力された LatestStreamArn をメモしておく。
"LatestStreamArn": "arn:aws:dynamodb:ap-northeast-1:012345678912:table/dynamodbtesttable/stream/2019-12-23T05:35:44.887"
2.Lambda 実行ロールの作成
LambdatestRole
を作成します。
信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
ロール
aws iam create-role --role-name LambdatestRole \
--path "/service-role/" \
--assume-role-policy-document file://trust-relationship.json
ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:publishNewtest*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:ap-northeast-1:123456789012:*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeStream",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:ListStreams"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/dynamodbtesttable/stream/*"
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": [
"*"
]
}
]
}
ロールにポリシーをアタッチ
aws iam put-role-policy --role-name LambdatestRole \
--policy-name LambdatestRolePolicy \
--policy-document file://role-policy.json
3.SNSトピックを作成する
トピック
aws sns create-topic --name snstestTopic
サブスクリプション
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:snstestTopic \
--protocol email \
--notification-endpoint example@example.com
E メールアドレスに届いた確認メッセージの [サブスクリプションを確認] リンクを選択して、サブスクリプションプロセスを完了します。
4.Lambda 関数の作成
コード
'use strict';
var AWS = require("aws-sdk");
var sns = new AWS.SNS();
exports.handler = (event, context, callback) => {
event.Records.forEach((record) => {
console.log('Stream record: ', JSON.stringify(record, null, 2));
if (record.eventName == 'INSERT') {
var who = JSON.stringify(record.dynamodb.NewImage.Username.S);
var when = JSON.stringify(record.dynamodb.NewImage.Timestamp.S);
var what = JSON.stringify(record.dynamodb.NewImage.Message.S);
var params = {
Subject: 'A new bark from ' + who,
Message: 'test user ' + who + ' barked the following at ' + when + ':\n\n ' + what,
TopicArn: 'arn:aws:sns:ap-northeast-1:accountID:snstestTopic'
};
sns.publish(params, function(err, data) {
if (err) {
console.error("Unable to send message. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Results from sending message: ", JSON.stringify(data, null, 2));
}
});
}
});
callback(null, `Successfully processed ${event.Records.length} records.`);
zip
zip publishNewBark.zip publishNewBark.js
ロールARNを確認。
```
aws iam get-role --role-name LambdatestRole
"Arn": "arn:aws:iam::123456789012:role/service-role/LambdatestRole "
```
Lambda関数の作成
aws lambda create-function \
--region ap-northeast-1 \
--function-name publishNewBark \
--zip-file fileb://publishNewBark.zip \
--role arn:aws:iam::123456789012:role/service-role/LambdatestRole \
--handler publishNewBark.handler \
--timeout 5 \
--runtime nodejs10.x
テスト用のpayload.jsonを作成
{
"Records": [
{
"eventID": "7de3041dd709b024af6f29e4fa13d34c",
"eventName": "INSERT",
"eventVersion": "1.1",
"eventSource": "aws:dynamodb",
"awsRegion": "ap-northeast-1",
"dynamodb": {
"ApproximateCreationDateTime": 1479499740,
"Keys": {
"Timestamp": {
"S": "2016-11-18:12:09:36"
},
"Username": {
"S": "naata"
}
},
"NewImage": {
"Timestamp": {
"S": "2016-11-18:12:09:36"
},
"Message": {
"S": "This is a bark from the test social network"
},
"Username": {
"S": "naata"
}
},
"SequenceNumber": "13021600000000001596893679",
"SizeBytes": 112,
"StreamViewType": "NEW_IMAGE"
},
"eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/dynamodbtesttable/stream/2019-12-23T05:35:44.887"
}
]
}
テストする。
$ aws lambda invoke --function-name publishNewBark --payload file://payload.json output.txt
{
"ExecutedVersion": "$LATEST",
"StatusCode": 200
}
output.txtに出力された内容を確認する。
"Successfully processed 1 records.
SNSメール通知されていることも確認。
5.本番テスト
dynamodbのArnを確認。
aws dynamodb describe-table --table-name dynamodbtesttable
"LatestStreamArn": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/dynamodbtesttable/stream/2019-12-23T05:35:44.887
イベントソースとAWS Lambda関数間のマッピングを作成
aws lambda create-event-source-mapping \
--region ap-northeast-1 \
--function-name publishNewBark \
--event-source arn:aws:dynamodb:ap-northeast-1:268546037544:table/dynamodbtesttable/stream/2019-12-23T05:35:44.887 \
--batch-size 1 \
--starting-position TRIM_HORIZON
dynamodbテーブルに項目を追加。
aws dynamodb put-item \
--table-name dynamodbtesttable \
--item Username={S="Jane Doe"},Timestamp={S="2016-11-18:14:32:17"},Message={S="Testing...1...2...3"}
SNS通知されたことを確認。
おしまい。