IAM Roleを割り当てたEC2インスタンスからEMRを起動する
いろいろとハマったのでメモ.
サマリ
- IAM Roleは3種類必要
- EMRをキックするインスタンス用の通常IAM Role
- EMRのservice role
- EMRで起動されるEC2用のjobflow role
- service / jobflow roleはdefaultを自動生成できるので使うべし
- AWSのドキュメントは英語版を見る方が結果的に早そう
- 日本語版は情報が古い
やろうとしていること
cronでデイリーにEMRを起動してS3のデータを集計する. 元々はサーバにAWSのトークン情報を抱かせて環境変数経由で渡して動いていたものを,IAM Roleを使う方式に変更することが目的.
条件は下記の通り.
- AWS
- サーバ(EC2)
- EMR Job
- S3のbucket Aにあるデータを入力
- 集計結果は別のbucket Bに保存される
やったこと
emr-kickerだけを設定 → 失敗
サーバのIAM Roleであるemr-kickerに必要な権限(EMR/EC2/S3など)を全て割り当てた. これでEMRを起動しようとすると
/path/to/vendor/bundle/ruby/2.1.0/gems/aws-sdk-1.48.1/lib/aws/core/client.rb:375:in 'return_or_raise': Service role and InstanceProfile are required for calls made with temporary credentials provided by STS (AWS::EMR::Errors::ValidationException)
となってコマンドが失敗する.
公式ドキュメントのAmazon EMR に IAM ロールを設定するから起動時にjobflow-roleを設定できることを知り,emr-jobflowというIAM Roleを新たに自前で作成してみるも,同じメッセージで起動できなかった.
よく見たらこのドキュメントにはIAM ロールでclusterを起動する方法は、現在 Amazon EMR コンソールではサポートされていません
などと書いてあった...
自前で用意したjobflow / service roleも設定 → 失敗
日本語のドキュメントでは情報が見つからなかったが,ググっているうちにDefault IAM Roles for Amazon EMRに当たった.
ここのデフォルト設定を元に,カスタムしたroleをそれぞれ(emr-service, emr-instance)作成し,service-role, jobflow-roleに設定するとコマンドは成功.
しかしAWS Consoleを見ると
Terminated with errors EMR service role arn:aws:iam::***************:role/emr-service is invalid
となって起動できていなかった.
default roleを生成してそのまま利用 → 成功
Default IAM Roles for Amazon EMRの末尾にある
- Create Default Roles with the CLI
を参考に,AWS CLIから下記コマンドでdefault roleを作成.
$ aws emr create-default-roles
このコマンドの結果,EMR_DefaultRole
とEMR_EC2_DefaultRole
がIAM Roleに追加される.
service-roleにEMR_DefaultRole
, jobflow-roleにEMR_EC2_DefaultRole
を指定したところ,上述のTerminated with erros
が出なくなり集計処理を実行することができた.
自前設定のroleで失敗して,デフォルトのroleだと成功した原因
IAM RoleのPermissionとは別の設定項目であるTrust Relationshipが正しく設定できていなかったためだった.
jobflow-roleをカスタム
EMR_EC2_DefaultRole
はS3やDynamoDBフルアクセスなど,かなり強い権限を持った状態なので,こちらは自前設定して必要範囲に絞った権限で利用することにした.