为 Amazon S3 配置外部卷

本主题介绍如何使用 Iceberg 表外部卷,向 Snowflake 授予对 Amazon S3 桶的受限访问权限。

组织中的管理员会在 Amazon Web Services (AWS) 账户中授予 IAM 用户权限。作为一项最佳实践,请创建指定的 IAM 策略,授予 Snowflake 对 S3 位置的访问权限。然后,您可以将该策略附加到角色,并使用由 AWS 为该角色生成的安全凭据来访问文件。

备注

  • Snowflake 不支持桶名称包含圆点的外部卷(例如 my.s3.bucket)。Snowflake 使用虚拟托管风格的路径和 HTTPS 访问 S3 中的数据。但 S3 不支持为名称中带有点的虚拟托管风格桶使用 SSL。

  • 必须在 AWS 中拥有创建和管理 IAM 策略和角色的权限,才能完成本主题中的说明。如果您不是 AWS 管理员,请让 AWS 管理员来执行这些任务。

  • 为支持数据恢复,为外部云存储位置启用版本控制

第 1 步:创建授予对 S3 位置的访问权限的 IAM 策略

要在 AWS 管理控制台中为 Snowflake 配置访问权限,请执行以下操作:

  1. 登录 AWS 管理控制台。

  2. 从主页仪表板搜索并选择 IAM

  3. 从左侧导航窗格中选择 Account settings

  4. Endpoints 列表中的 Security Token Service (STS) 下,找到账户所在位置对应的 Snowflake 区域。如果 STS status 处于非活动状态,请将切换键移动到 Active

  5. 从左侧导航窗格中选择 Policies

  6. 选择 Create Policy

  7. 对于 Policy editor,选择 JSON

  8. 添加策略,为 Snowflake 提供向 S3 位置读写数据所需的权限。以下示例策略授予对指定桶区中所有位置的访问权限。

    备注

    • 用实际桶名替换 bucket。您也可以在桶中指定路径;例如,bucket/path

    • "s3:prefix": 条件设置为 ["*"] 可授予对指定桶中所有前缀的访问权限;将其设置为 ["path/*"] 则可授予对桶中指定路径的访问权限。

    • 对于 政府区域 中的桶,桶 ARNs 使用 arn:aws-us-gov:s3::: 前缀。

    {
       "Version": "2012-10-17",
       "Statement": [
             {
                "Effect": "Allow",
                "Action": [
                   "s3:PutObject",
                   "s3:GetObject",
                   "s3:GetObjectVersion",
                   "s3:DeleteObject",
                   "s3:DeleteObjectVersion"
                ],
                "Resource": "arn:aws:s3:::<bucket>/*"
             },
             {
                "Effect": "Allow",
                "Action": [
                   "s3:ListBucket",
                   "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::<bucket>",
                "Condition": {
                   "StringLike": {
                         "s3:prefix": [
                            "*"
                         ]
                   }
                }
             }
       ]
    }
    
    Copy
  9. 选择 Next

  10. 输入 Policy name (例如 snowflake_access)和可选的 Description

  11. 选择 Create policy

第 2 步:创建一个 IAM 角色

创建一个可对包含数据文件的 S3 桶授予权限的 AWS IAM 角色。

  1. 在 Identity and Access Management (IAM) 控制面板的左侧导航窗格中,选择 Roles

  2. 选择 Create role

  3. 选择 AWS account 作为可信实体类型。

  4. An AWS account 下,选择 This account。在稍后的步骤中,您将修改信任关系,并授予对 Snowflake 的访问权限。

  5. 选择 Require external ID 选项。输入您选择的 外部 ID (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)。例如 iceberg-table-external-id

    外部 ID 用于向第三方(如 Snowflake)授予对 AWS 资源(例如 S3 桶)的访问权限。

  6. 选择 Next

  7. 选择您在第 1 步中创建的策略,该策略授予对 S3 位置的访问权限,然后选择 Next

  8. 输入角色的 Role name 和描述,然后选择 Create role

    您现在已经为一个 S3 位置创建了 IAM 策略,创建了一个 IAM 角色,并将策略附加到了该角色。

  9. 在角色摘要页面上,找到并记录角色的 ARN (Amazon 资源名称)值。

第 3 步:向 IAM 角色授予 SSE-KMS 加密所需的权限(可选)

如果要将使用 AWS KMS 密钥加密的对象上传到 Amazon S3,您在第 2 步中创建的 IAM 角色需要具备密钥的 kms:GenerateDataKey 权限。如果要下载使用 AWS KMS 密钥加密的对象,该 IAM 角色需要具备密钥的 kms:Decrypt 权限。

如果您想为服务器端加密使用 KMS 密钥,请按照这些步骤创建并应用此密钥。

  1. 在 AWS 管理控制台中,转到密钥管理服务 (KMS)。从左侧导航中选择 Customer managed keys,然后选择 Create key。必须在与桶相同的区域中创建密钥。

  2. 创建 Symmetric 密钥类型。对于密钥用法,选择 Encrypt and decrypt。选择 Next

  3. 对于 Alias,输入密钥的名称并选择 Next

  4. 如果需要,请为该密钥选择管理员,并选择 Next

  5. 对于 Define key usage permissions,请选择 IAM 角色,然后选择 Next

  6. 查看密钥配置详细信息,然后选择 Finish 以创建密钥。

  7. 在由客户管理的密钥列表中找到该密钥,选中它,并记录其 ARN。以下是一个密钥的 ARN 示例: arn:aws:kms:us-west-2:111111122222:key/1a1a11aa-aa1a-aaa1a-a1a1-000000000000

    在创建外部卷时,将 KMS_KEY_ID 的值设为您的密钥的 ARN。

第 4 步:在 Snowflake 中创建外部卷

使用 CREATE EXTERNAL VOLUME 命令创建外部卷。

以下示例创建一个外部卷,其中定义了一个采用加密的 Amazon S3 存储位置。该命令指定与第 2 步中创建的 IAM 角色关联的外部 ID (iceberg-table-external-id)。指定外部 ID 允许您跨多个外部卷使用相同的 IAM 角色(和外部 ID)。

CREATE OR REPLACE EXTERNAL VOLUME exvol
   STORAGE_LOCATIONS =
      (
         (
            NAME = 'my-s3-us-west-2'
            STORAGE_PROVIDER = 'S3'
            STORAGE_BASE_URL = 's3://MY_EXAMPLE_BUCKET/'
            STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/myrole'
            STORAGE_AWS_EXTERNAL_ID = 'iceberg-table-external-id'
            ENCRYPTION=(TYPE='AWS_SSE_KMS' KMS_KEY_ID='arn:aws:kms:us-west-2:111111122222:key/1a1a11aa-aa1a-aaa1a-a1a1-000000000000')
         )
      );
Copy

备注

完全按照 AWS 提供的方式指定 IAM 角色 ARN。ARNs 区分大小写。

第 5 步:检索您的 Snowflake 账户的 AWS IAM 用户

  1. 使用 DESCRIBE EXTERNAL VOLUME 命令,检索自动为 Snowflake 账户创建的 AWS IAM 用户的 ARN。指定在第 4 步中创建的外部卷的名称。

    例如:

    DESC EXTERNAL VOLUME exvol;
    
    Copy
  2. 记录 STORAGE_AWS_IAM_USER_ARN 属性的值,该属性是为 Snowflake 账户创建的 AWS IAM 用户;例如,arn:aws:iam::123456789001:user/abc1-b-self1234

    Snowflake 会为整个 Snowflake 账户配置单一 IAM 用户。账户中的所有 S3 外部卷均使用该 IAM 用户。

    备注

    如果创建外部卷时没有指定外部 ID (STORAGE_AWS_EXTERNAL_ID),Snowflake 会生成一个 ID 供您使用。记录该值,以便您可以使用生成的外部 ID 更新 IAM 角色信任策略。

第 6 步:授予 IAM 用户对桶对象的访问权限

在此步骤中,您要配置权限,以允许 Snowflake 账户的 IAM 用户访问 S3 桶中的对象。

  1. 登录 AWS 管理控制台。

  2. 从主页仪表板搜索并选择 IAM

  3. 从左侧导航窗格中选择 Roles

  4. 选择之前在第 2 步中创建的 IAM 角色。

  5. 选择 Trust relationships 选项卡。

  6. 选择 Edit trust policy

  7. 使用记录的 DESC EXTERNAL VOLUME 输出值,修改策略文档。

    其中:

    • snowflake_user_arn 是记录的 STORAGE_AWS_IAM_USER_ARN 值。

    • snowflake_external_id 是外部 ID。如果您在创建角色时 已经 指定了外部 ID,并使用相同的 ID 创建外部卷,请保持该值不变。否则,请使用记录的值更新 sts:ExternalId

    IAM 角色的策略文档

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "AWS": "<snowflake_user_arn>"
          },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": {
              "sts:ExternalId": "<snowflake_external_id>"
            }
          }
        }
      ]
    }
    
    Copy

    备注

    如果要新建外部卷(或使用 CREATE OR REPLACE EXTERNAL VOLUME 语法重新创建现有外部卷),则必须更新此策略文档,且不要提供您自己的外部 ID。出于安全原因,新的或重新创建的外部卷具有不同的外部 ID,除非您更新此信任策略,否则无法解析信任关系。

  8. 选择 Update policy 保存更改。

备注

要验证权限配置是否正确无误,请使用此外部卷 创建一个 Iceberg 表。在您创建引用此外部卷的 Iceberg 表之前,Snowflake 不会验证权限设置是否正确。

后续步骤

配置外部卷后,您可以创建 Iceberg 表。

语言: 中文