AWS-Glue

SSE-KMSで暗号化されたS3バケットをGlueで扱う際のKMS権限エラーを解消する

はじめに

こんにちは、omkです。

S3でSSE-KMSを利用する際に権限周りがややこしくなると思います。
今回はGlueでSSE-KMSで暗号化されたS3を利用する際に出たKMS周りの権限エラーをまとめようと思います。

やったこと

  1. クローラーでS3バケット中のファイルを「Glue Data Catalog」のテーブルに取り込み
  2. 「Glue Data Catalog」をAthenaからクエリ
  3. 「Glue job」で「Glue Data Catalog」経由でデータを読み書き

やってみた

準備

まずKMSキーを作成します。
カスタマー管理のキーから「対称キー」でキーの使用が「暗号化および復号化のキー」、キーマテリアルオリジンを「KMS」としてキーを作成します。
デフォルトのキーポリシーを設定します。

次にS3バケットを作成します。
デフォルトの暗号化を有効にし、暗号化キータイプをSSE-KMSに設定、KMSキーに作成したキーを設定します。
バケットポリシーやACLは設定しないです。

という感じに環境を用意しました。
なお、LakeFormationは余計にややこしくなるので今回は利用しないです。

S3バケット自体への読み書きの権限、Glue等の実行に必要な権限はある前提で進めます。

①クローラーでS3バケット中のファイルを「Glue Data Catalog」のテーブルに取り込み

コンソールからクローラーを作成して自動で作成されるIAMロールを割り当てました。
デフォルトではKMSの権限が設定されていないのでクローラーは正しくクローリングできないことが予想されます。

実行してみたところ、実行自体はCompletedで完了しましたが、「Table changes from last run」には何も出力されません。
CloudWatch Logsのログを見たところ以下のエラーが出力されています。

 ERROR : Not all read errors will be logged. com.amazonaws.services.s3.model.AmazonS3Exception: The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access.(Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

やはり権限でコケていますね……

クローラーに割り当てているIAMロールで作成した鍵に対する「kms:Decrypt」の権限を設定したところ、テーブルが作成され、ログからもエラーが消えました。
テーブルには正常にカラムが設定されているのでファイルを読み込むことができたことがわかります。

②「Glue Data Catalog」をAthenaからクエリ

では出来たData CatalogのテーブルをAthenaで確認しましょうか、ってなるかと思います。
こちらにもクエリを実行するIAMユーザー(ロール)に対してDecryptの権限が必要になります。

権限が無い場合ですと以下のようなエラーが表示され、結果は取得されません。

Permission denied on S3 path: s3://~~~~

こちらも「kms:Decrypt」の権限を設定することで解消されます。

③「Glue job」で「Glue Data Catalog」経由でデータを読み書き

作成されたテーブルをGlue Jobで加工するとします。

ジョブの中でData Catalogからテーブルを読み込む場合にもKMSキーの権限が必要です。

ただ、DynamicFrameで読み込んでDynamicFrame.show()するだけではエラーは出ませんでした(エラーが出ないだけでshow()の結果も空っぽでした)。

書き込みを行うと以下のようなエラーが表示されます。

An error occurred while calling o97.pyWriteDynamicFrame. The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access. (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

読み込み元のバケットのキーに対する権限が無いために本エラーが生じています。
Writeでエラーが出ていますが根本的な原因は読み込み時にDecrypt出来ていないことにあるのでキーに対する「kms:Decrypt」権限を付与します。

次に書き込み時のエラーその2。

An error occurred while calling o97.pyWriteDynamicFrame. User: arn:aws:sts::******:assumed-role/********* is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:ap-northeast-1:******:key/******* because no identity-based policy allows the kms:GenerateDataKey action (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

今度は書き込み先の暗号化キーでDataKeyを生成できないことが問題となります。
データキーを生成してそれを暗号化に利用するのでキーに対する「kms:GenerateDataKey」の権限が必要になります。

「kms:GenerateDataKey」の権限を与えたところ正常に書き込むことが出来ました。

おわりに

当然Glue Data Catalogで扱う場合でも通常のSSE-KMSのS3バケットの要件と合致するという内容でした。
ちなみにKMSキーのキーポリシーに使用するIAMユーザーなりIAMロールなりを設定することでKMS側で権限を与えることができ、IAM側で権限を与えずにキーを利用することが可能です。

以上、最後までお付き合いありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA