ちょっと話題の記事

Lambdaを使わずにS3にPutされたCSVファイルをRDSに自動一括登録する

S3へのCSVファイルのPutをトリガーにRDSにCSVファイルの中身を一括登録したいという要件 Lambdaを使用せずに実現する方法について調査しました!
2018.07.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

サーバーレス開発部@大阪の岩田です。

現在従事しているプロジェクトで、S3へのCSVファイルのPutをトリガーにCSVファイルの中身をRDSに一括登録したいという要件がありました。 S3へのPutをトリガーにLambdaを起動して〜というアーキテクチャはサーバーレス開発の定番ですがRDSへの一括登録となると話が変わってきます。 Lambdaの実行時間や、RDSへの同時接続数といった制限を意識しなくてはいけません。

実現方法としてCloudWatch Eventsのルールを使用してAWS Batchを起動する構成について調査したので、手順をご紹介します。

構成概要

今回ご紹介する構成は、下記のような構成です。

下記のエントリでも紹介されているように、2018年3月のアップデートにより、CloudWatch EventsをトリガーにAWS Batchのジョブが起動できるようになっています。 この機能を使用して環境を構築していきます。

[アップデート]AWS BatchがCloudWatch Eventsに対応しました!時間起動も可能に

注意点としては、

  1. 対象のS3バケットにCloudTrailを有効化しておくこと
  2. S3バケット、CloudTrail、AWS Batch全てのリソースを同一リージョンに作成していること

が挙げられます。

設定手順

実際に設定を行なっていきます。

S3バケットの作成とCloudTrailの有効化

まずは検証用のS3バケットを作成します

aws s3 mb s3://<対象のバケット名>

バケットが作成できたら、CloudTrailを有効化します。 前述のようにS3へのアクションをCloudWatch Eventとして受け取るためには対象のS3バケットにCloudTrailを設定する必要があるためです。

AWS Batchのジョブキュー作成

次にAWS Batchのジョブキューを作成します。 ウィザードに従って、デフォルトの設定でポチポチと進めていきます。

ジョブ定義の作成

ジョブキューが作成できたら、次はジョブ定義の作成です。 まずは定番のhello worldからはじめてみましょう。 hello worldとechoするだけの簡単なジョブを設定しています。

Cloud Watchのルール作成

AWS Batchの方が設定できたので、Cloud Watchイベントのルールを作成し、S3へのPutObjectをトリガーにAWS Batchのジョブを起動するよう設定します。

イベントソースに対象のS3バケットへのPutObjectを指定、ターゲットには先ほど作成したAWS Batchのジョブ定義を指定しています。

S3へのPutを試してみる

一通り設定ができたので、実際に動作確認してみましょう。 対象のS3バケットに適当にファイルをPutしてみます。

aws s3 cp test.txt s3://<対象のバケット名>

Cloud WatchLogsのログを確認

Cloud WatchLogsをのログを確認してみます。 AWS Batchのログは、ロググループ/aws/batch/jobの配下に出力されていきます。

hello worldと出力されています!! S3へのPutObjectをトリガーに、AWS Batchのジョブ実行まで、うまく流れていそうです。

Cloud Watchイベントの設定修正

ここまでで、S3へのPutObjectと連動してAWS Batchのジョブを実行するところまで成功しましたが、実際にCSVファイルをRDSに登録するには、ジョブに対してバケット名とオブジェクトキーを渡してやる必要があります。 CloudWatchのインプットトランスフォーマーという機能を使用して、ジョブにバケット名とオブジェクトキーを渡せるように設定してみます。

先ほど作成したCloud Watchイベントのルールを編集し、インプットトランスフォーマーの入力パスに

{"S3BucketValue":"$.detail.requestParameters.bucketName","S3KeyValue":"$.detail.requestParameters.key"}

と、入力テンプレートに

{"Parameters" : {"S3bucket": <S3BucketValue>, "S3key": <S3KeyValue>}}

と設定します。

これでAWS Batchのジョブ定義からS3bucketS3keyという名前のパラメータが参照できるようになりました。

ジョブ定義を修正

次にAWS Batchのジョブ定義を修正し、パラメータで渡されたS3バケット名とオブジェクトキーをechoするよう設定してみます。 ジョブ定義に渡されたパラメータはRef::パラメータ名という指定で参照できるので、ジョブ定義を下記のように修正します。

以下の画面キャプチャでS3Key(K大文字)となっていますが、画面キャプチャ時のミスです。 インプットトランスフォーマーの定義と合わせてS3key(k小文字)と設定して下さい。

再確認

aws s3 cp test.txt s3://<対象のバケット名>

再度適当なファイルをPutし、Cloud WatchLogsをのログを確認してみます。

バケット名、オブジェクトキーがログに出力されています。 この要領でバケット名、オブジェクトキーを引数に取り、CSVファイルをRDSに取り込むプログラムを実装すれば自動一括登録の環境構築完了です。

まとめ

Cloud Watchのイベントを使用して、AWS Batchのジョブを実行する方法について見てきました。 AWS Batchを利用することでLambdaの実行時間や、RDSへの同時接続数といった制限から解放されるため、CSVファイルの一括登録のようなユースケースではAWS Batchが有効な選択肢になるのではないでしょうか?

誰かの参考になれば幸いです。

参考