为 Amazon S3 配置外部卷

使用 Snowflake 中 Apache Iceberg™ 表的外部卷,向 Snowflake 授予对 Amazon S3 桶的受限访问权限。

作为一项最佳实践,请创建指定的 IAM 策略,授予 Snowflake 对 S3 位置的访问权限。然后,您可以将该策略附加到角色,并使用由 AWS 为该角色生成的安全凭据来访问文件。

备注

为了加强安全态势,您可以将外部卷配置为使用专用连接(而不是公共互联网)传输网络流量。有关更多信息,请参阅 AWS 外部存储卷的专用连接

先决条件

在配置外部卷之前,您需要具备以下条件:

  • S3 存储桶。

    • 要使用 Snowflake 作为目录,桶必须位于托管 Snowflake 账户的同一区域。

    • 要将外部卷用于外部管理的 Iceberg 表,您的所有表数据和元数据文件必须位于托管 Snowflake 账户的桶中。

    • 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

    在 AWS 管理控制台中创建一个 IAM 策略。
  7. 对于 Policy editor,选择 JSON

  8. 添加策略,为 Snowflake 提供向 S3 位置读写数据所需的权限。

    以下示例策略授予对指定桶区中所有位置的访问权限。

    备注

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

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

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

    • 如果您使用的是 S3 接入点,请指定接入点 ARN 而不是桶 ARN。有关更多信息,请参阅 配置使用接入点的 IAM 策略 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points-policies.html)。

    {
       "Version": "2012-10-17",
       "Statement": [
             {
                "Effect": "Allow",
                "Action": [
                   "s3:PutObject",
                   "s3:GetObject",
                   "s3:GetObjectVersion",
                   "s3:DeleteObject",
                   "s3:DeleteObjectVersion"
                ],
                "Resource": "arn:aws:s3:::<my_bucket>/*"
             },
             {
                "Effect": "Allow",
                "Action": [
                   "s3:ListBucket",
                   "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::<my_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 桶)的访问权限。

    创建一个具有外部 ID 的 IAM 角色。
  6. 选择 Next

  7. 选择您为外部卷创建的策略,然后选择 Next

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

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

  9. 选择 View role 以查看角色摘要页面。找到并记录角色的 ARN (Amazon Resource Name) 值。

    带有链接的横幅,用于查看新的 IAM 角色。

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

如果要将使用 AWS KMS 密钥加密的对象上传到 Amazon S3,您为外部卷创建的 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 命令创建外部卷。以下示例创建一个名为 iceberg_external_volume 的外部卷,其中定义了一个采用加密的 Amazon S3 存储位置。

CREATE OR REPLACE EXTERNAL VOLUME iceberg_external_volume
   STORAGE_LOCATIONS =
      (
         (
            NAME = 'my-s3-us-west-2'
            STORAGE_PROVIDER = 'S3'
            STORAGE_BASE_URL = 's3://<my_bucket>/'
            STORAGE_AWS_ROLE_ARN = '<arn:aws:iam::123456789012:role/myrole>'
            STORAGE_AWS_EXTERNAL_ID = 'iceberg_table_external_id'
         )
      );
Copy

该示例指定了与为外部卷创建的 IAM 角色关联的外部 ID (iceberg_table_external_id)。指定外部 ID 允许您跨多个外部卷使用相同的 IAM 角色(和外部 ID)。

备注

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

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

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

    以下示例描述了名为 iceberg_external_volume 的外部卷:

    DESC EXTERNAL VOLUME iceberg_external_volume;
    
    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. 选择为外部卷创建的 IAM 角色。

  5. 选择 Trust relationships 选项卡。

  6. 选择 Edit trust policy

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

    更新 IAM 角色的信任策略。

    IAM 角色的策略文档

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

    其中:

    • snowflake_user_arn 是记录的 STORAGE_AWS_IAM_USER_ARN 值。

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

    备注

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

  8. 选择 Update policy 保存更改。

第 7 步:验证存储访问

要检查 Snowflake 是否能成功对您的存储提供商进行身份验证,请调用 SYSTEM$VERIFY_EXTERNAL_VOLUME 函数。

SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('my_s3_external_volume');
Copy

后续步骤

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

语言: 中文