Amazon Redshift から別のアカウントの Amazon S3 バケットにデータをコピーまたはアンロードする方法を教えてください。

最終更新日: 2021 年 9 月 10 日

Amazon Redshift と別のアカウントの Amazon Simple Storage Service (Amazon S3) バケット間でデータをコピーまたはアンロードしようとしています。ただし、他のアカウントの AWS Identity and Access Management (IAM) ロールを引き受けることができません。クロスアカウントアクセスを設定する方法を教えてください。

簡単な説明

Amazon Redshift が使われているのとは別のアカウントにある Amazon S3 リソースにアクセスするには、以下の手順を実行します。

1.    Amazon S3 アカウントの IAM ロールである RoleA を作成します。

2.    RoleA を引き受けるアクセス許可を持つ Amazon Redshift アカウントの IAM ロールである RoleB を作成します。

3.    RoleARoleB 間のクロスアカウントアクセスをテストします。

注意:これらの手順はデータ形式に関係なく機能します。ただし、操作の実行中に COPY コマンドと UNLOAD コマンドのシンタックスが若干変更される場合があります。たとえば、Parquet データ形式を使用している場合、シンタックスは次のようになります。

copy table_name from 's3://awsexamplebucket/crosscopy1.csv' iam_role 'arn:aws:iam::Amazon_Redshift_Account_ID:role/RoleB,arn:aws:iam::Amazon_S3_Account_ID:role/RoleA format as parquet;

解決方法

注意: 以下のステップは、Amazon Redshift クラスターと S3 バケットが同じリージョンにあることを前提としています。リージョンが異なる場合は、COPY または UNLOAD コマンドに REGION パラメータを追加する必要があります。

Amazon S3 (RoleA) を使用しているアカウントに IAM ロールを作成する

1.    IAM コンソールを開きます。

2.    [ポリシー] を選択し、[ポリシーの作成] を選択します。

3.    [JSON] タブをクリックしてから、次のような IAM ポリシーを入力します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": [
                "<KMS_KEY_ARN_A_Used_for_S3_encryption>"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::awsexamplebucket",
                "arn:aws:s3:::awsexamplebucket/*"
            ]
        }
    ]
}

アクセスする S3 バケットの名前に awsexamplebucket を置き換えます。また、S3 バケットの暗号化に使用される AWS Key Management Service (AWS KMS) の Amazon リソースネーム (ARN) に KMS_KEY_ARN_A_Used_for_S3_encryption を置き換えます。

注意: S3 バケットが AWS KMS キーで暗号化されていない場合、AWS KMS のアクセス許可は必要ありません。

4.    [Review policy] (ポリシーの確認) をクリックします。

5.    ポリシー名 (policy_for_roleA など) を入力し、[Create policy] (ポリシーの作成) を選択します。

6.    ナビゲーションペインで、[Roles] (ロール) をクリックします。

7.    [Create role] (ロールの作成) を選択します。

8.    信頼されたエンティティロールの別の AWS アカウントを選択します。

9.    Amazon Redshift (RoleB) を使用しているアカウントの [AWS アカウント ID] を入力します。

10.    [Next: Permissions] (次へ: アクセス許可) を選択し、先ほど作成したポリシー (policy_for_roleA) を選択します。

11.    [Next: Tags]、それに続いて [Next: Review] を選択します。タグは必須ではないことに注意してください。

12.    ロール名 (RoleA など) を入力します。

13.    [Create role] (ロールの作成) を選択します。

RoleA を引き受けるアクセス許可を持つ Amazon Redshift アカウントに IAM ロール (RoleB) を作成する

1.    IAM コンソールを開きます。

2.    [ポリシー] を選択し、[ポリシーの作成] を選択します。

3.    [JSON] タブをクリックしてから、次のような IAM ポリシーを入力します。

{
    "Version": "2012-10-17",
    "Statement": [
            {
            "Sid": "CrossAccountPolicy",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "AmazonS3AccountRoleARN"
        }
    ]
}

AmazonS3AccountRoleARNRoleA (arn:aws:iam::Amazon_S3_Account_ID:role/RoleA) のARN に置き換えます。

4.    [Review policy] (ポリシーの確認) をクリックします。

5.    ポリシー名 (policy_for_roleB など) を入力し、[Create policy] (ポリシーの作成) を選択します。

6.    ナビゲーションペインで、[Roles] (ロール) をクリックします。

7.    [Create role] (ロールの作成) を選択します。

8.    信頼されたエンティティタイプとして [AWS のサービス] を選択します。

9.    [Redshift] をクリックします。

10.    [Redshift-Customizable] を選択します。

11.    [Next: Permissions] (次へ: アクセス許可) を選択し、先ほど作成したポリシー (policy_for_roleB) を選択します。

12.    [Next: Tags] (次へ: タグ)、[Next: Review] (次へ: 確認) の順に選択します。タグは必須ではないことに注意してください。

13.    ロール名 (RoleB など) を入力します。

14.    [Create role] (ロールの作成) を選択します。

15.    IAM ロール (RoleB) を Amazon Redshift クラスターに関連付けます

注意: Amazon Redshift で IAM ロールを連鎖することで、Amazon Redshift クラスターは RoleB を引き受け、その後に RoleA を引き受けます。このロールの連鎖により、Amazon Redshift が Amazon S3 にアクセスできるようになります。

S3 バケットと Amazon Redshift 間のクロスアカウントアクセスをテストする

COPY コマンドを実行して、S3 バケットから Amazon Redshift にデータをインポートします。

copy table_name from 's3://awsexamplebucket/crosscopy1.csv' iam_role 'arn:aws:iam::Amazon_Redshift_Account_ID:role/RoleB,arn:aws:iam::Amazon_S3_Account_ID:role/RoleA' delimiter ',' removequotes;

サンプルの以下の値を置き換えます。

table_name: Amazon S3 データのコピー先の Amazon Redshift テーブル
s3://awsexamplebucket/crosscopy1.csv: データのコピー元の S3 バケット
Amazon_Redshift_Account_ID: Amazon Redshift アカウントの AWS アカウント ID
RoleB: 作成した 2 番目のロール
Amazon_S3_Account_ID: Amazon S3 アカウントの AWS アカウント ID
RoleA: 作成した最初のロール

次に、UNLOAD コマンドを実行して Amazon Redshift から S3 バケットにデータをアンロードし、クロスアカウントアクセスを確認します。

unload ('select * from table_name') to 's3://awsexamplebucket/folder/table_name_' iam_role 'arn:aws:iam::Amazon_Redshift_Account_ID:role/RoleB,arn:aws:iam::Amazon_S3_Account_ID:role/RoleA' KMS_KEY_ID 'ARN_KMS_KEY_ID' ENCRYPTED;

サンプルの以下の値を置き換えます。

table_name: S3 バケットにアンロードする Amazon Redshift テーブル
s3://awsexamplebucket/folder/test.dat: Amazon Redshift データのアンロード先の S3 パス
Amazon_Redshift_Account_ID: Amazon Redshift アカウントの AWS アカウント ID
RoleB: 作成した 2 番目のロール
Amazon_S3_Account_ID: Amazon S3 アカウントの AWS アカウント ID
RoleA: 作成した最初のロール
ARN_KMS_KEY_ID: S3 バケットの暗号化に使用される KMS キー ID の ARN