EMR管理ポリシーをv1からv2に更新してみた
こんにちは、福岡オフィスのyoshihitohです。
先日、EMRの管理ポリシーをv1(非推奨化予定)からv2に更新する機会がありました。EMR管理ポリシーのv1とv2でどのような差異があるか、どういった対応を行ったか本記事にまとめます。
前提条件
対象
Amazon EMR on EC2
が対象ですAmazon EMR on EKS
とAmazon EMR Serverless
は対象外です
システム構成
筆者が運用するシステムではMWAAからEMRクラスタを構築して日次バッチを実行しています。日次バッチはS3に配置したデータを処理して、その結果をGlueのデータカタログに登録しています。このシステムで利用するEMR管理ポリシーをv1からv2に更新しました。
ポリシー更新
ポリシー更新にあたって以下の対応が必要です。
- EMRクラスタ構築時のリクエスト内容を変更する
- IAMロールの権限設定を変更する
- EMR関連リソースにタグを設定する
以降でそれぞれの対応について説明します。なお、更新の詳細や考慮事項については Amazon EMR管理ポリシー のドキュメントに詳細が記載されています。ドキュメントの内容を確認してから作業することをオススメします。
注意事項
・現在のすべてのエンティティから v1 ポリシーをデタッチすると、ポリシーは表示されなくなり、使用できなくなります。
Amazon EMR管理ポリシー のドキュメントに記載されている通り、v1ポリシーを使用するエンティティが無くなるとv1ポリシーは表示されなくなるようです。切り替え作業が終わるまでの間はv1ポリシーが非表示とならないように、何かしらのIAMエンティティにアタッチしておくと良いかもしれません。
EMRクラスタ構築時のリクエスト内容を変更する
RunJobFlow でEMRクラスタを構築するときに、リクエストの Tags
に以下の内容を設定してください。
- Key:
for-use-with-amazon-emr-managed-policies
- Value:
true
for-use-with-amazon-emr-managed-policies
タグを設定すると、EMRがプロビジョニングするリソースにタグを伝播するようになります。そのため後述するEMR管理ポリシーv2が要求するリソースタグの条件を満たすようになります。
IAMロールの権限設定を変更する
EMRクラスタで使用するIAMロールと、EMRクラスタを構築するアプリケーションで利用するIAMロールについて、アタッチするポリシーの変更が必要です。以下v1とv2の対応表です。
システム | ロール種別 | v1ポリシー | v2ポリシー |
---|---|---|---|
アプリケーション | フルアクセス | AmazonElasticMapReduceFullAccess | AmazonEMRFullAccessPolicy_v2 |
アプリケーション | 読み取り専用 | AmazonElasticMapReduceReadOnlyAccess | AmazonEMRReadOnlyAccessPolicy_v2 |
EMRクラスタ | EMRロール | AmazonElasticMapReduceRole | AmazonEMRServicePolicy_v2 |
EMRクラスタ | EC2インスタンスプロファイル | AmazonElasticMapReduceforEC2Role | - |
EMRクラスタ | Auto Scalingロール | AmazonElasticMapReduceforAutoScalingRole | AmazonElasticMapReduceforAutoScalingRole (変更なし) |
EMR on EC2では用途ごとに複数のロールがあり、それぞれのロールで利用できるEMR管理ポリシーが用意されています。EMRのデフォルトロールでは、以下のポリシーがアタッチされています。
ロール種別 | デフォルトロール | v1の場合 | v2の場合 |
---|---|---|---|
EMRロール | EMR_DefaultRole | AmazonElasticMapReduceRole | AmazonEMRServicePolicy_v2 |
EC2インスタンスプロファイル | EMR_EC2_DefaultRole | AmazonElasticMapReduceforEC2Role | - |
Auto Scalingロール | EMR_AutoScaling_DefaultRole | AmazonElasticMapReduceforAutoScalingRole | AmazonElasticMapReduceforAutoScalingRole (変更なし) |
EMRのデフォルトロールを使用しても良いし、システム固有のロールを作成することもできます。以降はシステム固有のロールを カスタムロール
と呼びます。ロール種別の詳細は Amazon EMR で使用される IAM サービスロール を確認してください。
EMR管理ポリシーをv1からv2に変更する場合は以下の対応が必要です。
- アプリケーションで利用するロールの権限設定を変更する
- EMRクラスタで利用するロールの権限設定を変更する
それぞれについて説明します。
アプリケーションで利用するロールの権限設定を変更する
EMRはフルアクセス用の管理ポリシーと、読み取り専用の管理ポリシーを用意しています。アプリケーションの目的に適したv2ポリシーをアタッチするように変更します。
- フルアクセスの場合:
AmazonEMRFullAccessPolicy_v2
- 読み取り専用の場合:
AmazonEMRReadOnlyAccessPolicy_v2
EMRクラスタで利用するロールの権限設定を変更する
以下の対応が必要です。
- EMRロール
- ロールにアタッチするポリシーを
AmazonEMRServicePolicy_v2
に変更する - (カスタムロールを利用する場合のみ)
EC2インスタンスプロファイル
(のロール) を対象としたiam:PassRole
を許可するポリシーを追加する
- ロールにアタッチするポリシーを
- EC2インスタンスプロファイル
AmazonElasticMapReduceforEC2Role
(v1ポリシー)をデタッチする- EMRクラスタ上で動作するアプリケーションが必要とする操作権限を持つポリシーを追加する
Auto Scalingロールについてはv1とv2で差異がないため対応不要です。
EMR管理ポリシーはv1とv2で権限設定が大幅に変わっています。以降でEMRロール夜の管理ポリシーととEC2インスタンスプロファイル用の管理ポリシーについて、v1とv2でどのような差異があるか確認していきます。
EMRロール
EMRロール向けの管理ポリシーは、EMRクラスタのリソースをプロビジョニングするために必要な操作を許可しています。v1とv2で対象リソースの条件が変わりました。
- v1 (
AmazonElasticMapReduceRole
)- 対象リソースの制限なし
- v2 (
AmazonEMRServicePolicy_v2
)for-use-with-amazon-emr-managed-policies
タグにtrue
を設定したリソースを対象とするfor-use-with-amazon-emr-managed-policies
タグにtrue
を設定したリクエストを対象とする- EMRのデフォルトロール
EMR_EC2_DefaultRole
とEMR_AutoScaling_DefaultRole
を対象とする
リソースのタグについては EMRクラスタ構築時のリクエスト内容を変更する と EMR関連リソースにタグを設定する を参照してください。
EC2インスタンスプロファイルもしくはオートスケーリングにカスタムロールを利用している場合、 iam:PassRole
でカスタムロールを指定する権限が必要です。この権限を持ったポリシーを作成してEMRロールにアタッチしましょう。
AWSアカウントID 123456789012
の環境で、EC2インスタンプロファイルに ec2-role
を、オートスケーリングに autoscaling-role
を使用する場合のIAMポリシーを例示します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/autoscaling-role", "Condition": { "StringLike": { "iam:PassedToService": "application-autoscaling.amazonaws.com*" } } }, { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/ec2-role", "Condition": { "StringLike": { "iam:PassedToService": "ec2.amazonaws.com*" } } } ] }
EC2インスタンスプロファイル
EC2インスタンスプロファイル向けの管理ポリシーは、EMRクラスタ上で動作するアプリケーションが必要とする操作を許可します。v1では管理ポリシー AmazonElasticMapReduceforEC2Role
が用意されていましたが、v2は同等の管理ポリシーを用意していません。EMRクラスタ上で動作するアプリケーションが必要とする操作権限を持ったポリシーを作成・アタッチしましょう。また、S3に配置したjarファイルをステップ実行する場合はS3のアクセス権限が必須となることに留意してください。
筆者が運用するシステムはSparkアプリケーションのjarファイルをS3に配置しています。SparkアプリケーションはS3とGlueを操作するため以下のようなポリシーを設定しました。実行するとまずい操作は個別に拒否しています。
{ "Version": "2012-10-17", "Statement": [ { "Action": "s3:*", "Resource": "*", "Effect": "Allow" }, { "Action": [ "s3:Create*", "s3:DeleteBucket*", ], "Resource": "*", "Effect": "Deny" }, { "Action": "glue:*", "Resource": "*", "Effect": "Allow" } ] }
EMR関連リソースにタグを設定する
EMRロール・EC2インスタンスプロファイルの詳細で確認したとおり、EMR管理ポリシーv2を利用する場合は、各リソースの for-use-with-amazon-emr-managed-policies
タグに true
を設定する必要があります。 EMRクラスタ構築時のリクエスト内容を変更する 対応後にEMRクラスタを起動すると、EMRが自動でほとんどのリソースにタグを伝播してくれます。ただし以下のリソースについては利用者側でタグを設定する必要があります。
- サブネット
- セキュリティグループ
セキュリティグループはEMRが自動で作成したものを利用する場合と、利用者が作成したものを利用する場合で扱いが異なります。
- EMRが自動で生成したものを利用する場合
- タグ設定不要 (EMRが設定するため)
- 利用者が作成したセキュリティグループを利用する場合
- タグ設定が必要
詳細はドキュメント 管理ポリシーを使用するためにリソースにタグを付ける を参照してください。筆者が運用するシステムの場合はEMRが作成したセキュリティグループを利用しているため、サブネットのみタグ設定が必要でした。
変更時にハマったこと
ドキュメントをちゃんと読まずにEMR管理ポリシーをv1からv2に付け替えてみたら盛大にハマりました。具体的には以下のエラーが発生しました。
- EMRクラスタ起動時に
Service role AppServiceRole has insufficient EC2 permissions
エラーが発生して起動に失敗する - Sparkアプリケーション実行ステップを追加すると、
AmazonS3Exception: Access Denied
エラーが発生して異常終了する
それぞれについてトラブルシュート方法とエラーの原因を記載します。
EMRクラスタ起動時に Service role AppServiceRole has insufficient EC2 permissions エラーが発生して起動に失敗する
EMR管理ポリシーをv1からv2に切り替えてからEMRクラスタを作成すると、 Service role AppServiceRole has insufficient EC2 permissions
エラーが発生して起動に失敗しました。
トラブルシュート方法
CloudTrailでエラーが発生した操作を特定しました。
- イベント履歴を開く
- EMRクラスタ作成日時周辺のイベントに絞り込む
- エラーが発生した操作を特定する
- イベント詳細を確認する
- 認証エラーの場合は、STSのDecodeAuthorizationMessage を使って
errorMessage
の詳細を復号し確認する
エラーの原因
以下の要因でエラーが発生していました。
EMRロール
がEC2インスタンスプロファイル
をiam:PassRole
する権限を許可していなかった- EMRが動作するサブネットに
for-use-with-amazon-emr-managed-policies
タグを設定していなかった
CloudTrailにこのようなエラーが記録されていました。
{ "eventTime": "2023-01-13T06:14:39Z", "eventSource": "ec2.amazonaws.com", "eventName": "RunInstances", "awsRegion": "ap-northeast-1", "sourceIPAddress": "elasticmapreduce.amazonaws.com", "userAgent": "elasticmapreduce.amazonaws.com", "errorCode": "Client.UnauthorizedOperation", "errorMessage": "You are not authorized to perform this operation. Encoded authorization failure message: CDzLM...(以下略)", }
errorMessage
を復号すると、以下のメッセージを確認できました。(抜粋です)
{ "allowed": false, "context": { "principal": { "id": "XXXXXXXXXXXXXXXXXXXXX:CCSSession", "arn": "arn:aws:sts::123456789012:assumed-role/ServiceRole/CCSSession" }, "action": "iam:PassRole", "resource": "arn:aws:iam::123456789012:role/JobFlowRole", "conditions": { "items": [ { "key": "aws:Region", "values": { "items": [ { "value": "ap-northeast-1" } ] } }, { "key": "aws:Service", "values": { "items": [ { "value": "ec2" } ] } }, { "key": "aws:Resource", "values": { "items": [ { "value": "role/JobFlowRole" } ] } } ] } } }
context
セクションの action
でエラー要因の操作がわかり、 resource
で操作対象のリソースがわかります。この場合は ServiceRole
がEC2に JobFlowRole
を iam:PassRole
しようとしたところ、権限不足で操作が拒否されたことがわかります。
これらのエラーを解消すると、EMRクラスタが起動するようになりました。
Sparkアプリケーション実行ステップを追加すると、 AmazonS3Exception: Access Denied
エラーが発生して異常終了する
EMRクラスタが起動するようになった後で、Sparkアプリケーション実行ステップを追加してみました。少し待つと Failed to get main class in JAR with error 'com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied
という内容のエラーが発生して異常終了しました。
トラブルシュート方法
EMRのステップを参照してエラーメッセージを確認しました。
ステップの処理まで進むとEMRのコンソール画面から詳細なエラーメッセージを確認できるようになるので対処しやすいですね。
エラーの原因
S3の操作権限がなく、ステップ実行で利用するjarファイルを取得するときに権限エラーとなっていました。
S3の操作権限と、EMRクラスタ上で動作するSparkアプリケーションが必要とする権限を付与して再実行したところ、ステップが正常終了するようになりました。
まとめ
EMR管理ポリシーをv1からv2に更新する場合は以下の対応が必要です。
- EMRクラスタ構築時のリクエスト内容を変更する
- RunJobFlow リクエストの
Tags
に{"Key": "for-use-with-amazon-emr-managed-policies", "Value": "true" }
を設定する
- RunJobFlow リクエストの
- IAMロールの権限設定を変更する
- 各ロールにアタッチするポリシーをv1からv2に付け替える
- EC2インスタンスプロファイルで利用するロールに、EMRクラスタ上で動作するアプリケーションが必要とする権限を追加する
- EMR関連リソースの
for-use-with-amazon-emr-managed-policies
タグにtrue
を設定する
おわりに
EMR管理ポリシーをv1からv2に移行する際に対応すべき内容と、実際のシステムで起こったエラーの内容について紹介しました。EMR管理ポリシーv2への移行を検討している方々のお役にたてると幸いです。