我的 Amazon S3 存储桶含有使用 UNLOAD 命令从另一个账户中的 Amazon Redshift 集群创建的数据文件。为什么我无法访问这些文件?

上次更新时间:2019 年 7 月 29 日

我的 Amazon Simple Storage Service (Amazon S3) 存储桶含有使用 UNLOAD 命令从另一个 AWS 账户中的 Amazon Redshift 集群创建的数据文件。但是,我在尝试从自己的账户访问这些文件时收到了 403 访问被拒绝错误。如何解决此问题? 

简短描述

默认情况下,S3 对象由上传它的 AWS 账户所拥有。即使存储桶归另一个账户所有,也是如此。由于来自 UNLOAD 命令的 Amazon Redshift 数据文件是由另一个账户放入您的存储桶的,您(存储桶拥有者)并没有访问这些文件的默认权限。

要获得这些数据文件的访问权限,必须使用具有跨账户权限的 AWS Identity and Access Management (IAM) 角色重新运行 UNLOAD 命令。请遵循以下步骤设置一个对存储桶拥有跨账户权限的 Amazon Redshift 集群:

1.    从 S3 存储桶的账户创建一个对该存储桶拥有权限的 IAM 角色(存储桶角色)。

2.    从 Amazon Redshift 集群的账户创建另一个拥有代入存储桶角色的权限的 IAM 角色(集群角色)。

3.    更新存储桶角色以授予对存储桶的访问权限,并创建与集群角色之间的信任关系。

4.    使用集群角色和存储桶角色从 Amazon Redshift 集群运行 UNLOAD 命令。

重要提示:此解决方法不适用于使用 AWS Key Management Service (AWS KMS) 进行服务器端加密的 Amazon Redshift 集群或 S3 存储桶。

解决方法

从 S3 存储桶的账户创建一个对该存储桶拥有权限的 IAM 角色(存储桶角色)

1.    从 S3 存储桶的账户打开 IAM 控制台

2.    创建一个 IAM 角色。创建该角色时,请选择以下选项:
对于选择受信任实体的类型,选择 AWS 服务
对于选择将使用此角色的服务,选择 Redshift
对于选择使用案例,选择 Redshift – 可自定义

3.    在创建该 IAM 角色后,附加一个策略以向该存储桶授予权限。您可以使用类似于以下内容的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234537676482",
      "Action": [
        "s3:ListBucket",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::awsexamplebucket/*",
        "arn:aws:s3:::awsexamplebucket"
      ]
    }
  ]
}

4.    获取存储桶角色的 Amazon 资源名称 (ARN)。您在稍后的步骤中将需要该角色的 ARN。

从 Amazon Redshift 集群的账户创建另一个拥有代入存储桶角色的权限的 IAM 角色(集群角色)

1.    从 Amazon Redshift 集群的账户打开 IAM 控制台

2.    创建一个 IAM 角色。创建该角色时,请选择以下选项:
对于选择受信任实体的类型,选择 AWS 服务
对于选择将使用此角色的服务,选择 Redshift
对于选择使用案例,选择 Redshift – 可自定义

3.    创建此 IAM 角色后,将以下策略附加到该角色:

重要提示:请将 arn:aws:iam::123456789012:role/Bucket_Role 替换为您创建的存储桶角色的 ARN。

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

4.    获取集群角色的 ARN。您在稍后的步骤中将需要该角色的 ARN。

更新存储桶角色以创建与集群角色之间的信任关系

1.    从 S3 存储桶的账户打开 IAM 控制台

2.    在导航窗格中,选择角色

3.    从角色列表中,打开您创建的存储桶角色。

4.    选择信任关系选项卡。

5.    选择编辑信任关系

6.    对于策略文档,请将现有策略替换为以下内容:

重要提示:请将 arn:aws:iam::012345678901:role/Cluster_Role 替换为您创建的集群角色的 ARN。

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

7.    选择更新信任策略

使用集群角色和存储桶角色从 Amazon Redshift 集群执行 UNLOAD 操作

1.    连接到 Amazon Redshift 集群

2.    使用您创建的两个 IAM 角色运行 UNLOAD 命令,与以下类似:

重要提示:请将 arn:aws:iam::012345678901:role/Cluster_Role 替换为您的集群角色的 ARN。然后,将 arn:aws:iam::123456789012:role/Bucket_Role 替换为您的存储桶角色的 ARN。

unload ('select * from TABLE_NAME')
to 's3://awsexamplebucket' 
iam_role 'arn:aws:iam::012345678901:role/Cluster_Role,arn:aws:iam::123456789012:role/Bucket_Role';

运行 UNLOAD 命令后,数据文件将由与存储它们的存储桶相同的账户拥有。


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助吗?