LambdaをつかってS3にPUTされた情報のメタデータをDynamoDBで楽に管理する


AWS Lambdaはre:Inventで発表された新しいコンピュートプラットフォームでクラウド上でコードスニペットをイベントドリブンで比較的簡単に動かせる特徴があります。例えばS3にデータがあがったとき、など今までだとどうしてもEC2をたてて、定期的にチェックをしながら動かす必要があったものが、文字通りS3側からイベントを発火してもらえるので、よけいなポーリングなどの手間がへり、結果的にコストをおさえながら目的を果たしやすくなっています。

そこで今回はS3上にあがったデータのメタデータをDynamoDBに管理するLambdaファンクションを作ってみたいと思います。


プレビューへの登録
-
まずはAWS Lambdaのプレビューを申し込みます。<a href="https://aws.amazon.com/jp/lambda/preview/">こちら</a>から申し込む事が出来ます。

プレビュー申し込みは順番に案内しているみたいなので、申し込んだらあとは祈るのみです。

ファンクションの作成
-

今回はS3にあがって来たデータのメタデータ管理をDynamoDBでやってみようと思います。あまり難しい事は考えずにシンプルに管理できるようにしてみましょう。旧来だとS3にあがったことをクライアント側でわざわざ通知したり、バッチ的にS3のLISTをコールしまくってメタデータを突っ込んでいたりとやや面倒でしたが、Lambdaを使うと結構シンプルにやれちゃいます。



ファンクションは下記にような感じになります。やってることは非常にシンプルで、
* Lambdaファンクションのeventからバケット名、キー名、ファイルサイズ、発火のきっかけとなったイベント、時刻、ソースIPなどを取得
* DynamoDBに突っ込む（テーブルは事前に作っておいてください）

こんだけです。注意点として、S3とLambdaのリージョンは現時点だと同じにする必要があります。DynamoDBは特に制約はないので東京リージョンにしてみます。

```js
var aws = require('aws-sdk');
var dynamo = new aws.DynamoDB({region: 'ap-northeast-1'});

exports.handler = function(event, context) {
        console.log('Received event:');
        console.log(JSON.stringify(event, null, '  '));
        // Get the object from the event and show its content type
        var bucket = event.Records[0].s3.bucket.name;
        var key = event.Records[0].s3.object.key;
        var size = String(event.Records[0].s3.object.size);
        var eventName = event.Records[0].eventName;
        var eventTime = event.Records[0].eventTime;
        var sourceIp = event.Records[0].requestParameters.sourceIPAddress;
        dynamo.putItem({"TableName":"s3-upload-history",
                "Item":{
                        "bucket":{"S":bucket},
                        "key":{"S":key},
                        "size":{"N":size},
                        "eventName":{"S":eventName},
                        "eventTime":{"S":eventTime},
                        "sourceIp":{"S":sourceIp}
        }
        }, function(err, data) {
                if(err) { console.log(err); }
                else { 
                        console.log("data uploaded successfully," + data);
                        context.done();
                }
        });
};
```



ファンクションの登録とデバッグ
-

ファンクションの登録自体はマネージメントコンソール上でぽちぽちとやってもらえれば良い感じです。細かいIAM Roleの設定などなどは、<a href="http://docs.aws.amazon.com/lambda/latest/dg/welcome.html">Lambdaのドキュメント</a>をご覧くださいませ。またCLIを使って、zipファイルに固めてもアップロードする事が出来ます。

コードが正しく動いているかを確認します。MC上でテストする機能がついているので、左側でサンプルのイベントをおこして、ちゃんと動いているかを確認します。

![ファンクションのデバッグとテスト](https://qiita-image-store.s3.amazonaws.com/0/1234/7ab117bf-c0c9-471c-c975-dd7ae1be6c4a.png "Screenshot 2014-11-24 13.45.09.png")



Invokeボタンをおすと、実際に動かす事が出来ます。ではDynamoDB側にも実際にデータが入ったか確認してみます。


![DynamoDBでのテストデータの確認](https://qiita-image-store.s3.amazonaws.com/0/1234/8e09e5f6-8adf-3f75-641f-9f197dc2cc17.png "Screenshot 2014-11-24 13.50.15.png")


どうやら入ってそうですね！


稼働確認
-

では実際にS3にオブジェクトをPUTしてみましょう。このLambdaファンクションのzip自体(s3todynamo.zip)をS3にあげてみます。


```bash
mypc:tmp shot6$ aws s3 cp s3todynamo.zip s3://lambda-s3dynamo-test/
upload: ./s3todynamo.zip to s3://lambda-s3dynamo-test/s3todynamo.zip
```


DynamoDB側でも確認してみましょう。
<br>



![DynamoDBでの実データでの確認](https://qiita-image-store.s3.amazonaws.com/0/1234/5b681550-f7ff-9c52-2b16-10efdfaaeeca.png "Screenshot 2014-11-24 13.51.36.png")



DynamoDB側でもデータが入っていますね！



まとめ
-

こんな感じで比較的あっさりとLambda上でS3のメタデータをDynamoDBで管理することが出来るようになりました。結構気楽に始められるのではないでしょうか？この他にも<b>Lambdaは色々クリエイティブに利用する事が出来る可能性を秘めたプラットフォーム</b>なので、他にも色々試してみたいと思います！


免責
こちらは個人の意見で、所属する企業や団体は関係ありません。