{DynamoDB}チュートリアル: DynamoDB Streams と Lambda を使用した新しい項目の処理

 


-- 1. ストリーミングが有効になった DynamoDB テーブルを作成する

aws dynamodb create-table \
--table-name tab1 \
--attribute-definitions \
    AttributeName=col1,AttributeType=S \
    AttributeName=col2,AttributeType=S \
--key-schema \
    AttributeName=col1,KeyType=HASH \
    AttributeName=col2,KeyType=RANGE \
--billing-mode=PAY_PER_REQUEST \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

 


-- 2. IAMポリシー作成
vim policy01.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:ap-northeast-1:999999999999:function:test"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-northeast-1:999999999999:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DescribeStream",
                "dynamodb:GetRecords",
                "dynamodb:GetShardIterator",
                "dynamodb:ListStreams"
            ],
            "Resource": "arn:aws:dynamodb:ap-northeast-1:999999999999:table/tab1/stream/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

aws iam create-policy \
--policy-name policy01 \
--policy-document file://policy01.json

-- 3. IAMロール作成
vim role01.json

{
   "Version": "2012-10-17",
   "Statement": [
     {
       "Effect": "Allow",
       "Principal": {
         "Service": "lambda.amazonaws.com"
       },
       "Action": "sts:AssumeRole"
     }
   ]
 }

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json


-- 4. ポリシーをロールにアタッチ
aws iam attach-role-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01 \
--role-name role01

 


-- 5. SNSトピック作成

aws sns list-topics
aws sns list-subscriptions

aws sns create-topic --name topic01

aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic01 \
--protocol email \
--notification-endpoint admin@example.com

 

-- 6. Lambda 関数作成

vim test.js

'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 col1 = JSON.stringify(record.dynamodb.NewImage.col1.S);
            var col2 = JSON.stringify(record.dynamodb.NewImage.col2.S);
            var col3 = JSON.stringify(record.dynamodb.NewImage.col3.S);
            var params = {
                Subject: 'A new data : ' + col1 + ',' + col2,
                Message: 'col3 : ' + col3,
                TopicArn: 'arn:aws:sns:ap-northeast-1:999999999999:topic01'
            };
            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 test.zip test.js

 

aws lambda create-function \
--region ap-northeast-1 \
--function-name test \
--zip-file fileb://test.zip \
--role arn:aws:iam::999999999999:role/role01 \
--handler test.handler \
--timeout 5 \
--runtime nodejs14.x


-- 7. トリガー作成
aws dynamodb describe-table --table-name tab1

aws lambda create-event-source-mapping \
--region ap-northeast-1 \
--function-name test \
--event-source arn:aws:dynamodb:ap-northeast-1:999999999999:table/tab1/stream/2021-09-25T17:18:19.200 \
--batch-size 1 \
--starting-position TRIM_HORIZON

-- 8. 動作確認

aws dynamodb put-item \
--table-name tab1  \
--item \
    '{"col1": {"S": "val11"}, "col2": {"S": "val12"}, "col3": {"S": "val13"}}'

aws dynamodb put-item \
--table-name tab1 \
--item \
    '{"col1": {"S": "val21"}, "col2": {"S": "val22"}, "col3": {"S": "val23"}}'

aws dynamodb delete-item \
--table-name tab1 \
--key '{ "col1": {"S": "val21"}, "col2": {"S": "val22"}}'


-- 9. クリーンアップ

-- lambdaイベントソースマッピング一覧

aws lambda list-event-source-mappings \
--function-name test \
--event-source arn:aws:dynamodb:ap-northeast-1:999999999999:table/tab1/stream/2021-09-25T17:18:19.200 \

-- lambdaイベントソースマッピング削除
aws lambda delete-event-source-mapping \
--uuid 11111111-2222-3333-4444-555555555555


-- lambda関数の一覧
aws lambda list-functions | jq -c '.Functions[] | [ .FunctionName ]'

-- lambda関数の削除
aws lambda delete-function --function-name test

-- SNSトピック削除

aws sns unsubscribe --subscription-arn arn:aws:sns:ap-northeast-1:999999999999:topic01:11111111-2222-3333-4444-555555555555
aws sns delete-topic --topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic01

aws sns list-topics
aws sns list-subscriptions

 

-- ロールの一覧
aws iam list-roles | grep role01

-- ロールの削除

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::999999999999:policy/policy01


aws iam delete-role --role-name role01

-- ポリシーの一覧
aws iam list-policies | grep policy01

-- ポリシーの削除
aws iam delete-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01


-- dynamodbテーブル一覧
aws dynamodb list-tables

-- dynamodbテーブル削除
aws dynamodb delete-table --table-name tab1