Amazon Web Services ブログ
Amazon S3 で AWS KMS 暗号化データのクロスアカウント Amazon Redshift COPY および Redshift Spectrum クエリを有効にする方法
この記事では、Amazon S3 のサンプルデータセットを使用してクロスアカウントの Amazon Redshift COPY および Spectrum クエリを設定する方法を段階的に説明します。サンプルデータセットは、AWS KMS で管理されたキー (SSE-KMS) を使用して保管時に暗号化されます。
AWS Key Management Service (AWS KMS) について
AWS Key Management Service (AWS KMS) を使用すると、保管中のデータを保護するために使用される暗号化キーを集中管理することができます。データの暗号化に使用する暗号化キーの作成、インポート、ローテーション、無効化、削除、使用ポリシーの定義、および使用の監査ができます。AWS KMS は FIPS 140-2 検証済み暗号化モジュールを使用して、マスターキーの機密性と整合性を保護します。
AWS KMS は、ほとんどの AWS のサービスとシームレスに統合されています。この統合により、簡単にカスタマーマスターキー (CMK) を使用して、これらのサービスに保存されているデータの暗号化を制御することができます。Amazon Redshift などのサービスでデータを暗号化すると決めると、Amazon Redshift が KMS で自動的に作成する AWS 管理の CMK を使用することを選択できます。キーの使用状況を追跡することはできますが、それはお客様ではなくサービスによって管理されています。場合によっては、CMK のライフサイクルを直接管理する必要がある場合や、他のアカウントに CMK の使用を許可したい場合があります。このような場合は、Amazon Redshift などの AWS のサービスがお客様に代わって使用できる独自の CMK を作成および管理することができます。こうした顧客管理の CMK を使用すると、誰がキーを使用できるか、どのような条件下で使用できるかを決めるアクセス許可を完全に制御することができます。AWS KMS は、AWS KMS でユーザー、ロール、または AWS のサービスによって実行されたアクションの記録を提供するサービスである AWS CloudTrail と統合されています。
Amazon Redshift および Redshift Spectrum について
Amazon Redshift は、ペタバイト規模の、AWS 上の完全マネージド型のデータウェアハウスサービスです。分散型の超並列処理 (MPP)、シェアードナッシングアーキテクチャを採用して、使用要件に合わせて水平方向に拡張します。
Amazon Redshift Spectrum は、データウェアハウスのローカルディスクに保存されているデータを超えて Amazon Redshift の分析機能を拡張する Amazon Redshift の機能です。言い換えれば、Amazon Redshift Spectrum を使用すると、Amazon S3 データレイクに保存されているデータに対して、Amazon Redshift と同じ ANSI SQL 構文を使用できます。最初に Amazon Redshift にデータを取り込むことなく、外部テーブルを使用してこれを行います。一般的なパターンは、Amazon Redshift にローカルに保存されている頻繁にアクセスされる「ホット」なデータと、Amazon S3 にコスト効率よく保存されている「ウォーム/コールド」なデータの両方にまたがるクエリを実行することです。このパターンは、ユースケースに合わせて両方を独立してスケーリングできるようにすることで、コンピューティングとストレージを分離します。つまり、ストレージを追加するためだけに使用しないコンピューティングキャパシティーに対して支払う必要がないことを意味します。さらに重要なことは、このアプローチがデータレイクと Amazon Redshift の間でのシームレスな相互運用を可能にすることです。
Amazon Redshift COPY コマンドは、次のタイプの Amazon S3 暗号化をサポートしています。
- Amazon S3 が管理するキー (SSE-S3) によるサーバー側での暗号化
- AWS KMS が管理するキー (SSE-KMS) によるサーバー側での暗号化
- クライアント側の対称マスターキーを使用したクライアント側での暗号化
Amazon Redshift COPY コマンドは、次のタイプの Amazon S3 暗号化はサポートしていません。
- 顧客が提供するキー (SSE-C) によるサーバー側での暗号化
- AWS KMS が管理するカスタマーマスターキーによるクライアント側での暗号化
- 顧客が提供する非対称マスターキーによるクライアント側での暗号化
ユースケースについて
AWS 環境で複数のアカウントを持つのは、さまざまな理由から多くの顧客に共通するパターンです。AWS でデータレイクを利用する顧客にとっての一般的な理由の 1 つは、データ資産の所有権を社内のさまざまな事業部門から切り離すことです。同時に、事業部門は、新しい事業に関する洞察を得るために、データ資産の一部へのアクセス許可を互いに許可する必要があります。
次の図に示すように、この例では、アカウント A は SSE-KMS 暗号化データを含む S3 バケットを所有し、アカウント B は Redshift Spectrum を有効にした Amazon Redshift クラスターを所有しています。COPY コマンドを使用して Amazon Redshift クラスターにロードし、Redshift Spectrum を使用してクエリも実行するには、アカウント B が同じデータにアクセスする必要があります。
ソリューションのウォークスルー
続いて、このユースケースをサポートするいくつかの異なるオプションを検討します。
前提条件
このソリューションでは、以下の設定がすでに行われていることを前提としています。
-
- 同じ AWS リージョンにある 2 つの AWS アカウント (アカウント A および B と呼びます) へのアクセス。*
- AWS アカウントへの AdministratorAccess ポリシーの付与 (本稼働ではさらに制限)。
- アカウント A に、以下の属性を備えた顧客管理の CMK が AWS KMS にある:
- kms_key_account_a というエイリアス
- アカウント A のクロスアカウント KMS キーという説明
- AWS コンソールにサインインして KMS キーを作成した現在の IAM ユーザーとしての管理者
- 外部アカウントとして追加されたアカウント B
まもなく使用する CMK の Amazon リソースネーム (ARN) をコピーして保存
- アカウント A は、AWS の以下のサンプルデータセットを使用:
- アカウント A に、rs-xacct-kms-bucket という S3 バケットがあり、前に作成した KMS キー kms_key_account_a を使用してバケット暗号化オプションを AWS KMS に設定している。
- 次の AWS CLI コマンドを使用して、Amazon Redshift ドキュメントにある AWS サンプルデータセットSSB – Sample Schema Benchmark から顧客テーブルデータをコピーします。注意: バケット名はすべての AWS 顧客にわたってグローバルであるため、テスト実行には一意のバケット名が必要です。次のコマンドで、必ず rs-xacct-kms-bucket を自分のバケット名に置き換えます。
- コピーが完了したら、次に示すように、S3 コンソールからファイルの KMS キー IDを確認します。
- アカウント B に、以下のような Amazon Redshift クラスターがある:
- クラスター名は rstest
- 一般に公開されている
- redshift_role_account_b という IAM ロールがアタッチされており、次の 2 つのマネージド型 IAM ポリシーがある:
- AmazonS3ReadOnlyAccess
- AWSGlueConsoleFullAccess
注意: 必ず redshift_role_account_b を自分の IAM ロールで更新します。
ラップトップの SQL Workbench などのクライアントツールからデータベースセッションを正常に設定することができます。
* このウォークスルーでは、US-West-2 (オレゴン) リージョンで公開されている AWS サンプルデータセットを使用します。そのため、テスト実行には US-West-2 (オレゴン) リージョンを使用して、データ移動による地域間ネットワークのレイテンシーとコストを削減することをお勧めします。
段階的なウォークスルー
どのアカウントの AWS Glue データカタログを Redshift Spectrum に使用するかに応じて、2 つのソリューションの選択肢から選択できます。
- アカウント B の AWS Glue データカタログ
- アカウント A の AWS Glue データカタログ
選択肢 1: アカウント B の AWS Glue データカタログ
アクセス許可の設定
- アカウント A の AWS コンソールにサインインします。次に、AWS リージョンを us-west-2 (オレゴン) に変更します。アカウント B (Amazon Redshift クラスター – rstest を所有する) がバケットにアクセスできるように、rs-xacct-kms-bucket バケットに以下のバケットポリシーを追加します。
注意: <Account B> をアカウント B の AWS アカウント ID で、rs-xacct-kms-bucket をバケット名で置き換えます。
-
- アカウント B の AWS コンソールにサインインします。次に、AWS リージョンを us-west-2 (オレゴン) に変更します。以下の説明に従って、IAM ポリシーとロールを作成します。
a) 次の 2 つの IAM アクセス許可ポリシーを作成します: アカウント B にアカウント A の S3 バケットへのアクセス権を与える rs_xacct_bucket_policy、アカウント B にアカウント A の CMK へのアクセス権を与えrs_xacct_kms_policy。
ポリシー名: rs_xacct_kms_policy
注意: <ARN of kms_key_account_a from Account A> をアカウント A の KMS キー ARN で置き換えます。
ポリシー名: rs_xacct_bucket_policy
注意: rs-xacct-kms-bucket を自分のバケット名で置き換えます。
b) 以下の IAM ポリシーをアタッチして、Amazon Redshift サービス用に xacct_kms_role_account_b という新しい IAM ロールを作成します:
• rs_xacct_bucket_policy
• rs_xacct_kms_policy
• AWSGlueConsoleFullAccess
IAM ロールの Amazon リソース ネーム (ARN) を保存します。すぐにそれを使います。
c) ここで、2つの IAM ロール、redshift_role_account_b と xacct_kms_role_account_b の間で Amazon Redshift 用の IAM ロールチェーンを設定します。
ロールをチェーンするには、ロール間に信頼関係を確立します。別のロール (たとえば、ロール A) を引き受けるロールには、次にチェーンされるロール (たとえば、ロール B) を引き受けることを許可するアクセス許可ポリシーが必要です。同様に、アクセス許可を渡すロール (ロール B) には、前にチェーンされたロール (ロール A) にアクセス許可を渡すことを許可する信頼ポリシーが必要です。
チェーンで最初のロールは、Amazon Redshift クラスターにアタッチされているロールである必要があります。チェーン内で最初のロールと次のロールを引き受けるそれ以降の各ロールには、特定のステートメントを含むポリシーが必要です。このステートメントは、sts:AssumeRole アクションおよび Resource エレメント内の次のロールの ARN に Allow 効果を与えます。
この例では、ロール A は redshift_role_account_b であり、これにはアクセス許可ポリシー rs_xacct_assume_role_policy が必要です。これにより、ロール A はロール B (xacct_kms_role_account_b) を引き受けることができます。どちらの IAM ロールも、AWS アカウント B によって所有されています。
d) それでは、IAM アクセス許可ポリシー rs_xacct_assume_role_policy を作成し、そのポリシーを IAM ロール redshift_role_account_b にアタッチしましょう。
ポリシー名: rs_xacct_assume_role_policy
注意: <ARN for IAM role xacct_kms_role_account_b from Account B> を置き換えます。
e) [Edit trust relationship] を選択し、既存の信頼ポリシーを以下に置き換えて、IAM ロール xacct_kms_role_account_b の信頼関係を変更します。
注意: <Account B> をアカウント B の AWS アカウント ID で置き換えます。
f) 以下のポリシーをアタッチして、glue_service_role_account_b という AWS Glue サービスの IAM ロールを作成します:
• AWSGlueServiceRole (AWS マネージドポリシー)
• rs_xacct_bucket_policy (前に作成したマネージドポリシー)
• rs_xacct_kms_policy (前に作成したマネージドポリシー)
注意: 必ず glue_service_role_account_b を自分の IAM ロールで更新します。
Amazon Redshift COPY を実行する
- クエリツールから Amazon Redshift クラスターにログインし、以下の DDL を使用して customer テーブルを作成します。
2.これで、以下の COPY ステートメントを正常に実行することができます。
注意: アカウント B の IAM ロール ARN を、前後にスペースを入れずにコンマで区切って置き換えます。
3.次のサンプルクエリを実行して、データが正常に読み込まれたことを確認します。
Redshift Spectrum が照会する AWS Glue データカタログテーブルを設定する
以下の手順に従って、アカウント B に AWS Glue クローラを作成し、同じ customer データをクロールし、AWS Glue データカタログデータベース spectrumdb_account_b に customer というテーブルを作成します。
- AWS Glue コンソールで [Databases] に移動し、[Add database] を選択し、次のように spectrumdb_account_b という AWS Glue データカタログデータベースを作成します。
- AWS Glue コンソールで [Crawlers] に移動し、次のように [Add crawler] を選択します。
- 次に示すように、クローラ customerxacct を作成します。
注意: クローラのジョブ名 (この場合は customerxacct) は、クローラによって作成されたテーブル名と同じではありません (よくある混乱)。テーブル名は、S3 バケットとフォルダ構造のプレフィックスとフォルダ名から自動的に選択されます。必要に応じて、テーブル名のプレフィックスを付けることもできます。
- 次のように、[Next] を選択して顧客テーブルのデータストア詳細を入力します。
- [Next] を選択して [Add another data store] に移動します。追加するデータストアは他にないため、デフォルトの [No] のままにします。
- 以下に示すように、[Next] を選択して、クローラが使用するために以前に作成した IAM ロール glue_service_role_account_b を選択します。
- [Next] をクリックして [Schedule] ページに移動し、このクローラジョブを実行するスケジュールを選択します。この例では、[Run on demand] を選択します。
- [Next] を選択して、クローラの出力場所として AWS Glue データカタログデータベースの spectrumdb_account_b (外部スキーマ作成コマンドで前に作成したもの) を選択します。
- [Next] を選択して、確認ページに移動します。
- 詳細を確認したら、[Finish] を選択してクローラの作成を終了します。
- ここで、次のようにジョブを選択して [Run crawler] を選択し、クローラジョブを実行します。
- しばらく待って、ジョブが完了するのを確認します。ステータスが「Starting」から「Stopping」、「Ready」へと変わります。更新ボタンを選択して、最新の状態にすることができます。
- ジョブが失敗すると、失敗は Amazon CloudWatch logs に記録されます。ログを表示するには、前のスクリーンショットに示されるように [Logs] を選択すると、CloudWatch logs に移動します。
- それでは、AWS Glue データカタログデータベースに移動して、テーブルが存在することを確認しましょう。
[Databases]、[spectrumdb_account_b] データベース、[View Tables] の順に選択するか、データベース名のハイパーリンクを選択します。次に示すように、customer テーブルが表示されます。
- customer ハイパーリンクを選択して外部テーブルにアクセスすると、以下のような詳細が表示されます。
データファイルにヘッダーレコードがないため、AWS Glue クローラは前述のようにデフォルトの列命名規則を割り当てました。customer テーブルの場合、この命名は列 0 から列 7 までです。
- [Edit Schema] を選択し、以下のマッピングに従って、適切な列名を割り当てます。
c0 => c_custkey
c1 => c_name
c2 => c_address
c3 => c_city
c4 => c_nation
c5 => c_region
c6 => c_phone
c7 => c_mktsegment
操作が終わったら、[Save] を選択します。
Redshift Spectrum クエリを実行する
これで、customer テーブルが AWS Glue データカタログに作成されたので、Redshift Spectrum を使用してテーブルを照会しましょう。
- クエリツールから Amazon Redshift クラスターにログインします。
- 次のステートメントを実行して、AWS Glue データカタログデータベースを指す Redshift Spectrum 用に spectrumxacct という外部スキーマを作成します。このデータベースは、AWS Glue コンソールですでに作成されている、アカウント B の spectrumdb_account_b です。
注意: アカウント B の IAM ロール ARN を、前後にスペースを入れずにコンマで区切って置き換えます。
- 以下のサンプルクエリを実行して、Redshift Spectrum がデータを正常に照会できることを確認します。
注意: Redshift Spectrum は、アカウント A ではなくアカウント B で AWS Glue データカタログを使用します。
選択肢 2: アカウント A の AWS Glue データカタログ
アクセス許可の設定
1.アカウント A の AWS コンソールにサインインし、AWS リージョンを us-west-2 (オレゴン) に変更します。
-
-
a) 以下の IAM ポリシーを作成します:
• rs-xacct-bucket-policy、アカウント A の S3 バケットへのアクセスを許可する
• rs_xacct_kms_policy、アカウント A の CMK へのアクセスを許可する
ポリシー名: rs_xacct_bucket_policy
注意: バケット名 rs-xacct-kms-bucket を自分のバケット名で置き換えます。
ポリシー名: rs_xacct_kms_policy
注意: <ARN of kms_key_account_a from Account A> をアカウント A の KMS キー ARN で置き換えます。
b) 以下の IAM ポリシーを使用して、Amazon Redshift サービス用に xacct_kms_role_account_a という新しい IAM ロールを作成します:
• rs_xacct_bucket_policy
• rs_xacct_kms_policy
• AWSGlueConsoleFullAccess (このマネージドポリシーは AWS Glue データカタログに必要なアクセス許可を提供します)
すぐに使用する IAM ロール ARN を保存します。
c) [Edit trust relationship] を選択し、既存の信頼ポリシーを以下に置き換えて、IAM ロール xacct_kms_role_account_b の信頼関係を変更します。
注意: <Account B> をアカウント B の AWS アカウント ID で置き換えます。
d) 以下のポリシーをアタッチして、glue_service_role_account_a という AWS Glue サービスの IAM ロールを作成します:
• AWSGlueServiceRole (AWS マネージドポリシー)
• rs_xacct_bucket_policy (前に作成したマネージドポリシー)
• rs_xacct_kms_policy (前に作成したマネージドポリシー)
注意: 必ず glue_service_role_account_a を自分の IAM ロールで更新します。
2.アカウント B の AWS コンソールにサインインし、まだ選択していない場合は、AWS リージョンを us-west-2 (オレゴン) に変更します。
a) 既存の IAM ポリシー rs_xacct_assume_role_policy を変更し、既存の JSON ポリシーを以下と置き換えます:
注意: <ARN for IAM role xacct_kms_role_account_a from Account A> を置き換えます。
Amazon Redshift COPY を実行する
1.クエリツールから Amazon Redshift クラスターにログインし、以下の DDL を使用して customer テーブルを作成します。
2.これで、以下の COPY ステートメントを正常に実行することができるはずです。
注意: IAM ロール ARN を、前後にスペースを入れずにコンマで区切って置き換えます。
3.以下のサンプルクエリを実行して、データが正常に読み込まれたことを確認します。
Redshift Spectrum が照会する AWS Glue データカタログテーブルを設定する
以下の手順に従って、アカウント A に AWS Glue クローラを作成し、同じ customer データをクロールし、アカウント A の AWS Glue データカタログデータベース spectrumdb_account_a に customer というテーブルを作成します。
選択肢 1 と同じ手順に従って、次の変更を加えてクローラを作成して実行します。
- 今回は、(選択肢 1 のアカウント B ではなく) アカウント A にクローラを作成します。
- アカウント A に AWS Glue データカタログデータベース spectrumdb_account_a (アカウント B に spectrumdb_account_b ではなく) を作成し、customer テーブルを作成するためにクローラ用にそのデータベースを選択します。
- S3 パスを指定し、オプション [Specified path in my account] を選択します (選択肢 1 の場合の [Specified path in another account] とは異なります)。
- 必ず、AWS Glue サービスの IAM ロールとして、前に作成した glue_service_role_account_a を使用します。
Redshift Spectrum クエリを実行する
これで、customer テーブルが AWS Glue データカタログに作成されたので、Redshift Spectrum を使用してテーブルを照会しましょう。
1.クエリツールから Amazon Redshift クラスターにログインして、以下のステートメントを実行します。これらのステートメントは、アカウント A の AWS Glue データカタログデータベース spectrumdb_account_a (前に AWS Glue コンソールで作成) を指す Redshift Spectrum 用の spectrumxacct2 という外部スキーマを作成します。
注意: IAM ロール ARN を、前後にスペースを入れずにコンマで区切って置き換えます。
2.次のクエリを実行します。正常に実行されるはずです。
注意: Spectrum は、アカウント B ではなくアカウント A で AWS Glue データカタログを使用します。
まとめ
この記事では、Amazon S3 でサンプルの KMS 暗号化データセット用に Redshift Spectrum を使用してクロスアカウントの Amazon Redshift COPY とクエリを設定する方法を段階的に説明しました。どのアカウントの AWS Glue カタログを Redshift Spectrum に使用するかに応じて選択する 2 つのソリューションの選択肢も示しました。
ご不明な点がございましたら、コメントをお寄せください。
著者について
Asim Kumar Sasmal は、AWS プロフェッショナルサービスのグローバルスペシャリティプラクティスの IoT 担当シニアデータアーキテクトです。彼は、AWS プラットフォームで専門的な技術コンサルティング、ベストプラクティスに関するガイダンス、実装サービスを提供することによって、世界中の AWS 顧客がデータ駆動型ソリューションを設計および構築するのを支援しています。彼は、顧客の要望から逆向きに取り組み、大きな思考を手助けし、AWS プラットフォームの力を活用して現実のビジネスの問題を深く掘り下げて解決することに情熱を注いでいます。