IAM RoleのChaining(ロール連鎖)を利用して、別AWSアカウントのS3バケットからRedshiftへCOPYをする

2020.09.12

こんにちは!DA(データアナリティクス)事業本部 インテグレーション部の大高です。

RedshiftにS3のファイルからデータをCOPYコマンドでロードする際に「同一AWSアカウント上のS3バケットからロードする」というケースがよくあるかと思います。一方で、場合によっては「別AWSアカウントのS3バケットからデータをロードしたい」というケースもあります。

この場合の対応方法として、「IAM RoleのChaining(ロール連鎖)」を利用する方法が下記のドキュメントに記載されていました。

今回、実際にこの方法でCOPYを試してみたので内容をまとめたいと思います。

全体概要

まずはじめに全体の概要です。設定が複雑なので図にしてみました。

同一AWSアカウント内の場合は、RedshiftにIAMロールをアタッチして、そのIAMロールにS3バケットへのアクセスポリシーが記載される形となります。

一方、今回は別AWSアカウントのS3バケットからデータをロードしたいので、登場人物としてはIAMロール(図の右側のIAMロール)がもう1つ増えている形となっています。

前提条件について

今回は既に図中のRedshiftクラスター(COPY先 Redshift)は立ち上がっており、S3バケット(COPY元 バケット)についても作成済みの前提で話をすすめます。

では、環境ごとに設定をみていきます。

Redshift環境での設定

Redshift環境では、まず始めにIAMロール(RoleA)を作成します。AWSの管理コンソールから「IAM」サービスの画面を開き、新規にIAMロールを作成します。

IAMロールの作成では信頼されたエンティティに「AWSサービス」を指定し、サービスには「Redshift」、ユースケースには「Redshift - Customizable」を指定します。

ポリシーの設定はこの時点ではなにも選択せずに進み、タグについては任意の設定を行ってIAMロールの作成は完了です。

なお、作成したIAMロールのARNについては、あとで必要になるので控えておきます。

次に、このIAMロールをRedshiftクラスタの設定画面からアタッチします。Redshiftクラスタの画面を開き「プロパティ」タブの「クラスターのアクセス許可」にある「IAMロールの管理」ボタンからロールのアタッチができます。

この「IAMロールの管理」画面で、先程作成したIAMロールを選択して追加、保存すればアタッチができます。

これで、以下の図の赤枠の部分が設定された状態となります。

では、一旦ここまでにしてS3環境の設定に移ります。

S3環境での設定

続いて、S3環境でもIAMロールを作成してきます。

IAMロールの作成では信頼されたエンティティに「別のAWSアカウント」を指定し、「アカウントID」にはRedshift環境のアカウントID(この例では999999999999)を指定します。

ポリシーについては、本来IAMポリシーを作成してアタッチすべきですが、今回は簡略化のためにインラインポリシーを後から指定するので、一旦ポリシー設定はスキップしてIAMロールを作成します。タグについては任意の設定をしておきます。

また、こちらのIAMロールのARNもあとで必要になるので控えておきます。

作成後に、改めてIAMロールの「信頼関係」を編集します。

ポリシードキュメントのPrincipalに、控えておいたRedshift環境で作成したIAMロールのARNを指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::999999999999:role/RoleA"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

次に、「アクセス権限」に以下のようなインラインポリシーを設定し、S3バケットへのアクセス権限を付与します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::s3-bucket-b/*"
            ],
            "Effect": "Allow"
        }
    ]
}

これで、S3環境においては、以下の図の緑枠の部分が設定された状態となります。

Redshift環境での設定(再)

最後に、改めてRedshift環境のIAMロールにポリシーを設定します。

こちらも今回は手順を簡略化してインラインポリシーを利用して以下のように設定します。ResourceのARNには、先程控えておいたS3環境で作成したIAMロールのARNを指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::000000000000:role/RoleB"
        }
    ]
}

これで、Redshift環境における、以下の図の青枠の部分が設定された状態となり、すべて設定が完了しました。

COPYコマンドを実行する

最後に、実行するCOPYコマンドについてです。

COPYコマンドは以下のようになります。変わっている点はIAM_ROLEの指定の仕方となります。

通常は1つのIAMロールを指定しますが、Role Chainingを利用するので、最初にRedshiftと信頼関係を結んでいるRoleAを指定し、次にカンマ区切りでRoleAと信頼関係を結んでいるRoleBを指定します。

また、IAM_ROLEの指定は全体をシングルクォーテーションで括るスペースを含めてはならないという点にご注意ください。

COPY
  public.sample_table
FROM
  's3://s3-bucket-b/sample_data/'
IAM_ROLE
  'arn:aws:iam::999999999999:role/RoleA,arn:aws:iam::000000000000:role/RoleB'
;

このコマンドを実行することで、別AWSアカウントのS3バケットからRedshiftへCOPYをすることができました!

なお、今回は試していませんが冒頭に挙げたドキュメントによると最大で10連鎖までいけるそうです。ばよえ~ん。

最大で 10 個のロールを連鎖できます。

まとめ

以上、Role Chaining(ロール連鎖)を利用した、別AWSアカウントのS3バケットからRedshiftへCOPYする方法のご紹介でした。

なんとなく「できるだろうな」とは思ってはいたのですが、実際に試してみることでRole Chainingの設定の流れが理解できて面白かったです。

どなたかのお役に立てば幸いです。それでは!