現在作っているEMRでのバッチ処理が月次で行えば良いものなので、毎回EMRをマネジメントコンソールから立ち上げるのもめんどくさいですし、定期実行させるためのサーバを立てるのもめんどくさいですし、定期実行するLambdaで連携してみます。
Lambda Functionの作成
-
とりあえずLambdaを開いて
-
blueprint, triggerは特に設定せずにSkip
定期実行するLambdaの設定に関しては、こちらから(http://qiita.com/RyujiKawazoe@github/items/64e8a65ab3e4909678fc)
-
Lambdaの設定を行う
私の場合は、JavaでLambdaの実行コードを記述しています。
jarを直接アップロードorS3から読み込ませる2択になるのですが、For files larger than 10 MB, consider uploading via S3.
のように、jarサイズが10MBを超える場合はS3にまずjarをアップロードし、jarのURLを"S3 Link URL"に入れてください。(jarのURLをpublishにする必要はありません)
Handlerには、Lambdaが実行するクラス、メソッド名を指定してください
パッケージ.クラス::メソッド
Roleについては後述します。
-
あとはReviewしてOK押せば、作成完了です。
Lambdaに設定するIAM Roleについて
私が作成したLambdaアプリケーションは、以下の振る舞いをするものです。
- S3のオブジェクトチェック
- 1でチェックしたオブジェクトがなければEMR起動
なのでLambdaに設定するRoleは
- S3にアクセスできるもの
- EMRにアクセスできるもの
- LambdaがLogを作成できるもの(これは最初S3のテンプレートを選んだためデフォルトで付いてました)-> "S3 read-only permissions"
となります。
ただ、"S3 read-only permissions"だけ選んで、S3オブジェクト存在チェックを行うと(コードは以下)
final AmazonS3 s3Client = new AmazonS3Client();
final String s3ObjectPath = "aaa/bbb/ccc/ddd.txt"
s3Client.doesObjectExist(BUCKET_NAME, s3ObjectPath);
のように
s3Client.doesObjectExist
メソッドを読んだら、403エラーが起きたので
Lambdaに設定するIAM Roleは以下のようにしています。
(正直絞り込んだ方がいいと思うのですが、めんどくさいのでとりあえず)