如何将 Amazon Redshift 中的数据复制或卸载到另一账户中的 Amazon S3 存储桶?

上次更新日期:2022 年 11 月 1 日

我想在 Amazon Redshift 和另一个账户中的 Amazon Simple Storage Service (Amazon S3) 存储桶之间对数据执行复制或卸载操作。但是,我无法在其他账户中代入 AWS Identity and Access Management (IAM) 角色。如何设置跨账户访问?

简短描述

要访问使用 Amazon Redshift 的其他账户下的 Amazon S3 资源,请执行以下步骤。以下步骤适用于 Redshift 无服务器和 Redshift 预置的数据仓库

1.    创建 RoleA,即 Amazon S3 账户中的 IAM 角色。

2.    创建 RoleB,即 Amazon Redshift 账户中具有代入 RoleA 的权限的 IAM 角色。

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 存储桶位于同一区域中。如果它们位于不同的区域中,那么您必须将 REGION 参数添加到 COPYUNLOAD 命令中。

在使用 Amazon S3 的账户中创建 IAM 角色 (RoleA)

1.    打开 IAM console(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/*"
      ]
    }
  ]
}

awsexamplebucket 替换为您想访问的 S3 存储桶的名称。此外,将 KMS_KEY_ARN_A_Used_for_S3_encryption 替换为用于加密 S3 存储桶的 AWS Key Management Service (AWS KMS) 的 Amazon Resource Name (ARN)。

注意:如果 S3 存储桶未使用 AWS KMS 密钥加密,则不需要 AWS KMS 权限。

4.    选择 Review policy(查看策略)。

5.    输入策略的名称(例如 policy_for_roleA),然后选择 Create policy(创建策略)。

6.    从导航窗格中选择 Roles(角色)。

7.    选择 Create role(创建角色)。

8.    为受信任实体角色选择 Another AWS account(另一个 AWS 账户)。

9.    对于 AWS 账户 ID,输入使用 Amazon Redshift 的账户的 ID (RoleB)。

10.    选择 Next: Permissions(下一步: 权限),然后选择刚创建的策略 (policy_for_roleA)。

11.    选择 Next: Tags(下一步: 标签),然后选择 Next: Review(下一步: 检查)。请注意,标签不是必选项。

12.    输入角色名称(例如 RoleA)。

13.    选择 Create role(创建角色)。

在具有 RoleA 代入权限的 Amazon Redshift 账户中创建 IAM 角色 (RoleB)

1.    打开 IAM console(IAM 控制台)。

2.    依次选择策略创建策略

3.    选择 JSON 选项卡,然后输入类似以下内容的 IAM 策略:

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

RoleA (arn:aws:iam::Amazon_S3_Account_ID:role/RoleA) 的 ARN 替换 AmazonS3AccountRoleARN

4.    选择 Review policy(查看策略)。

5.    输入策略的名称(例如 policy_for_roleB),然后选择 Create policy(创建策略)。

6.    从导航窗格中选择 Roles(角色)。

7.    选择 Create role(创建角色)。

8.    选择 AWS service(AWS 服务)作为您的受信任实体类型。

9.    选择 Redshift

10.    选择 Redshift - Customizable(Redshift – 可定制)。

11.    选择 Next: Permissions(下一步: 权限),然后选择刚创建的策略 (policy_for_roleB)。

12.    选择 Next: Tags(下一步: 标签),然后选择 Next: Review(下一步: 检查)。请注意,标签不是必选项。

13.    输入角色名称(例如 RoleB)。

14.    选择 Create role(创建角色)。

15.    将 IAM 角色 (RoleB) 与您的 Amazon Redshift 集群相关联:

        对于预置的 Redshift 集群,请参阅将 IAM 角色与集群相关联

        -或者-

        对于 Redshift 无服务器,请参阅将 IAM 角色分配给 Amazon Redshift 无服务器中安全和连接的命名空间

注意:通过串联 Amazon Redshift 中的 IAM 角色,Amazon Redshift 集群代入 RoleB,Role B 再代入 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 Redshift 表,您要将 Amazon S3 数据复制到此表
s3://awsexamplebucket/crosscopy1.csv:S3 存储桶,您要从中复制数据
Amazon_Redshift_Account_ID:Amazon Redshift 账户的 AWS 账户 ID
RoleB:您创建的第二个角色
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:Amazon Redshift 表,您要将此表分流到 S3 存储桶
s3://awsexamplebucket/folder/test.dat:要将 Amazon Redshift 数据分流到的 S3 路径
Amazon_Redshift_Account_ID:Amazon Redshift 账户的 AWS 账户 ID
RoleB:您创建的第二个角色
Amazon_S3_Account_ID:Amazon S3 账户的 AWS 账户 ID
RoleA:您创建的第一个角色
ARN_KMS_KEY_ID:用于加密 S3 存储桶的 KMS 密钥 ID 的 ARN