AWS Lambda と Amazon DynamoDB Streams を連係する

2014.12.08

Amazon DynamoDB Streams とは

Amazon DynamoDB Streams (以下 DynamoDB Streams) とは、先日発表された DynamoDB の新機能です。この機能を有効にすることで、DynamoDB のテーブルに対するすべての更新(Put, Update, Delete)が直近の24時間保持され、API 経由でアクセスできるようになります。

DynamoDB のテーブルの更新などのイベントがフックできるため、これをきっかけに別なテーブルに更新をかけたり、SNS で通知したり、用途に応じてさまざまな処理を行うことができます。

この DynamoDB Streams ですが、現在(2014/12/08)のところ Sneak Preview となっているため、利用申請を出して通過するまで利用できません。ということで Preview が通過したので、早速使ってみたいと思います。

DynamoDB Streams の有効化

Preview を通過すると、次のようなメールが届きます。

dynamodb-stream01

この中の一番上の「US East (N. Virginia): Access preview console here.」のリンクをクリックすると、US-East-1 リージョンで DynamoDB Streams を試すことができます。

dynamodb-stream02

ということで、まずは DynamoDB テーブルを新規作成しました。すると、「Streams」というタブが新しく増えていることが確認できます。

dynamodb-stream04

ここの「Enable New Stream」をクリックします。すると「View Type」というものを設定する画面が表示されます。

dynamodb-stream03

View Type は、対象とする Item の条件を設定する項目です。次のいずれかを設定できます。

  • Keys Only - Key (Hash Key, Range Key) の値が変更された Item に関してのみ(only the key attributes of the modified item)
  • New Image - Item が変更された直後のみ(the entire item, as it appears after it was modified)
  • Old Image - Item が変更された直前のみ(the entire item, as it appeared before it was modified)
  • New and Old Images - New Image, Old Image の両方とも(both the new and the old images of the item)

作成後「Status」が「Enabled」になったら、イベントが保存されるようになります。今回は「New and Old Images」にしました。

これで DynamoDB テーブルの Item の変更イベントが保存されるようになりました。

Lambda で DynamoDB のイベントをフックする

次に Lambda さんの出番です。まずは Lambda ファンクションを新規作成します。

dynamodb-stream06

Lambda ファンクションのコードは次のようにします。対象の DynamoDB テーブルの Item の情報を出力しているだけです(公式ドキュメント参考)。

console.log('Loading event');
exports.handler = function(event, context) {
  console.log("Event: %j", event);
  for(i = 0; i < event.Records.length; ++i) {
    record = event.Records[i];
    console.log(record.eventID);
    console.log(record.eventName);
    console.log("DynamoDB Record: %j", record.Dynamodb);
  }
  context.done(null, "Hello World");  // SUCCESS with message
}
[/javascript]

<p>
IAM Role の Policy は <tt>logs:*</tt> のアクションを許可するように設定します。デフォルトのままで構いません。
</p>

{  
   "Statement":[  
      {  
         "Action":[  
            "logs:*"
         ],
         "Effect":"Allow",
         "Resource":"arn:aws:logs:*:*:*"
      }
   ]
}

ということで Lambda ファンクションが完成しました。

dynamodb-stream07

最後に DynamoDB Streams と Lambda を連係させます。先ほど作成した DynamoDB の Management Console に戻りましょう。「Associate Lambda Function」ボタンがありますね!

dynamodb-stream05

クリックすると Associate Lambda Function の設定メニューが表示されます。

dynamodb-stream09

Select a Lambda Function

実行する Lambda ファンクションです。先ほど作成した Lambda ファンクションを選択します。

Starting Point

対象となる Item が複数あるときの実行順です。Latest (降順) または Trin Horizon (未実行の古い順) のいずれかを設定できます。

Batch Size

1回の Lambda ファンクションの処理で実行する Item の数を指定します(1〜100)。

Lambda Function Invoke Role

Lambda ファンクションを実行 (Invoke) するために DynamoDB サービスに与える IAM Role です。指定した Lambda ファンクションが実行できるような Policy を設定していれば問題ありません。

実行してみよう

整いました。実行してみましょう!対象の DynamoDB Table に Item を追加します。

dynamodb-stream10

ログを見てみると、、出力されています!

dynamodb-stream11

まとめ

ということで、Lambda の無限の可能性の1つである DynamoDB Streams を用いた DynamoDB テーブルのイベントフックでした。今回試す上で、次のような問題がありましたので、うまく実行できない場合の参考にしてください。Preview なので、悪しからずといったところでしょうか。

  • 一度作成した Stream が消せない (Disable にはなるが、消せないらしい)
  • Associate Lambda Function の 設定が反映されないことがある (設定画面に前回の値が反映されない?)
  • イベントがフックできず、Lambda ファンクションが実行されないことがある (時間を置くと実行される)

DynamoDB Streams 自体は、設定も簡単なので導入しやすいイメージを持ちました。 リリースが待ち遠しいですね!