如何使用与 Amazon Redshift 在同一个账户的 Amazon S3 存储桶的 Redshift Spectrum 解决访问被拒绝错误?

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

我想要访问存储在与我的 Amazon Redshift 集群在同一个账户中的 Amazon Simple Storage Service (Amazon S3) 存储桶中的数据。我还想使用以 AWS Glue 作为数据目录的 Amazon Redshift Spectrum 来访问数据。但是,我收到了权限错误。

简短描述

附加到 Redshift 集群的 AWS Identity and Access Management (IAM) 角色必须拥有 AWS Glue 和 S3 服务的权限。如果 IAM 角色没有正确的权限,则您可能会收到以下任何错误:

创建外部架构时:

SQL Error [XX000]: ERROR: 
  User: arn:aws:sts::111111111111:assumed-role/KCARole/RedshiftIamRoleSession is not authorized to perform: glue:CreateDatabase on resource: arn:aws:glue:eu-west-1:111111111111:catalog because no identity-based policy allows the glue:CreateDatabase action

尝试查询 Redshift Spectrum 表时:

SQL Error [XX000]: ERROR: Spectrum Scan Error
  Detail: 
  -----------------------------------------------
  error:  Spectrum Scan Error
  code:      15007
  context:   Forbidden: HTTP response error code: 403 Message: AccessDenied Access Denied

在尝试查询 Redshift Spectrum 表且 S3 存储桶使用 Key Management Services (AWS KMS) 加密密钥时:

SQL Error [XX000]: ERROR: Spectrum Scan Error
  Detail: 
  -----------------------------------------------
  error:  Spectrum Scan Error
  code:      15007
  context:   Forbidden: HTTP response error code: 403 Message: AccessDenied The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access

要解决这些错误,您必须将具有所需权限的 IAM policy 附加到 Amazon Redshift 使用的 IAM 角色。如果使用 KMS 密钥加密 S3 存储桶,则还必须附加权限才能使用该密钥。

解决方法

将 AWS 托管式策略 AWSGlueConsoleFullAccess 附加至附加到 Redshift 集群的 IAM 角色。

使用以下示例创建 IAM policy,并将该策略附加到附加到 Redshift 集群的 IAM 角色。这允许对存储数据的 S3 存储桶进行读取访问:

注意:存储桶名称替换为您的 S3 存储桶的名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Allows Redshift to Read S3 bucket specified",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::<bucket name>/*",
        "arn:aws:s3:::<bucket name>"
      ]
    }
  ]
}

如果 Redshift Spectrum 使用的 S3 存储桶是使用 AWS KMS 加密密钥加密的,则创建并附加以下 IAM policy。将策略附加到附加到 Redshift 集群的 IAM 角色。此策略提供访问权限,这样 Redshift Spectrum 就可以解密 Amazon S3 中的加密数据。以下是允许解密的最低权限示例:

注意:区域替换为您的 S3 存储桶所在的 AWS 区域,将 AWS 账户 ID 替换为您的账户 ID,并将 KMS 密钥 ID 替换为 KMS 加密密钥。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Allow Redshift to use the KMS key",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
      ],
      "Resource": [
        "arn:aws:kms:<region>:<AWS account ID>:key/<KMS key ID>"
      ]
    }
  ]
}