为 pg_lake 配置 S3 存储

pg_lake 是 PostgreSQL 扩展,能够高效查询存储在 Parquet 和 ORC 等对象存储格式中的数据。将 pg_lake 与 Snowflake Postgres 结合使用时,您需要通过使用 Snowflake 存储集成来配置对存储数据的 Amazon S3 桶的访问权限。

本主题介绍如何配置 AWS 上的 S3 桶权限,并创建一个允许 Snowflake Postgres 访问您的数据的存储集成。

备注

目前,此 S3 存储不属于 Snowflake Postgres 托管范围。您需要提供自己的 S3 桶,并通过附加到 Postgres 实例的存储集成来配置访问权限。

先决条件

在为 pg_lake 配置 S3 存储之前,请确保您已具备:

  • 一个活跃的 AWS 账户,且具有创建和管理 S3 桶 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html) 以及 IAM 角色 (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) 的权限。

  • 一个与您的 Snowflake 账户位于同一 AWS 区域的 S3 桶。要确定您的 Snowflake 账户区域,请在 Snowflake 中(而非 Postgres 实例上)执行以下查询:

    SELECT CURRENT_REGION();
    
  • 熟悉 AWS IAM 角色和策略 (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)。

  • 具有 pg_lake 支持的 Snowflake Postgres 实例。

  • 在 Snowflake 中创建存储集成的权限(需要 ACCOUNTADMIN 角色,或在账户上拥有 CREATE INTEGRATION 权限的角色)。

第 1 步:创建 S3 桶

如果您还没有 S3 桶,请在您的 Snowflake 账户所在的同一 AWS 区域中创建一个。例如,如果您的 Snowflake 账户位于 us-west-2,请在 us-west-2 区域创建 S3 桶。

有关说明,请参阅 AWS 文档中的 创建 S3 桶 (https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html)。

第 2 步:创建用于 S3 访问的 IAM 策略

创建 IAM 策略,授予 pg_lake 从 S3 桶读取及向其写入数据所需的必要权限:

  1. 登录 AWS 管理控制台并导航至 IAM 服务。

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

  3. 在端点列表中的 Security Token Service (STS) 下,找到账户所在位置对应的 Snowflake 区域。如果 STS 状态处于非活动状态,请将切换键移动到 Active。有关更多信息,请参阅 在 AWS 区域激活和停用 AWS STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)。

  4. 从左侧导航窗格中选择 Policies,然后选择 Create policy。

  5. 对于 Policy editor,选择 JSON。

  6. 添加允许 Snowflake 访问 S3 桶和文件夹的策略文档。将 bucket_name 和 prefix 替换为您实际的桶名称和文件夹路径前缀:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject",
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:DeleteObject",
                    "s3:DeleteObjectVersion"
                ],
                "Resource": "arn:aws:s3:::bucket_name/prefix/*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:GetBucketLocation"
                ],
                "Resource": "arn:aws:s3:::bucket_name",
                "Condition": {
                    "StringLike": {
                        "s3:prefix": [
                            "prefix/*"
                        ]
                    }
                }
            }
        ]
    }
    

    此策略提供的权限包括:

    • 读取、写入和删除指定 S3 路径中的对象

    • 列出桶内容并检索桶位置

    • 支持 pg_lake 创建和管理 Iceberg 表的能力

  7. 选择 Next。

  8. 输入策略名称(例如,snowflake_pg_lake_access)和可选描述。

  9. 选择 Create policy。

第 3 步:创建 IAM 角色

创建供 Snowflake 承担的 IAM 角色,以访问您的 S3 桶。

重要

创建此角色时,您必须将 Maximum session duration 设置为 12 hours。存储集成无法在默认会话持续时间下工作。请参阅本节的最后一步。

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

  2. 选择 Create role。

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

  4. 选择 Another AWS account。

  5. 在 Account ID 字段中,暂时输入自己的 AWS 账户 ID。在稍后的步骤中,您将修改信任关系,并授予对 Snowflake 的访问权限。

  6. 选择 Require external ID 选项。输入占位符外部 ,例如 ID。您将在后续步骤中使用 Snowflake 生成的实际外部 ID 来更新此内容。

    备注

    外部 ID 用于向第三方(如 Snowflake)授予对 AWS 资源(例如 S3 桶)的访问权限。有关更多信息,请参阅向第三方授予 ` 资源访问权限时 ID如何使用外部 AWS <https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)>`_。

  7. 选择 Next。

  8. 搜索并选择您在 第 2 步:创建用于 S3 访问的 IAM 策略 中创建的策略。

  9. 选择 Next。

  10. 为角色输入名称和描述(例如,snowflake_pg_lake_role),然后选择 Create role。

  11. 在角色摘要页面上,找到 Role ARN 值并将其记录下来。在 Snowflake 中创建存储集成时,您将需要此信息。

  12. 在角色摘要页面上,选择摘要部分的 Edit,并将 Maximum session duration 更改为 12 hours。选择 Save changes。有关更多信息,请参阅 修改角色最大会话持续时间 (AWS) (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)。

第 4 步:在 Snowflake 中创建存储集成

在 Snowflake 中创建一个引用您所建 IAM 角色的存储集成对象。有关完整的命令语法,请参阅 CREATE STORAGE INTEGRATION。

CREATE STORAGE INTEGRATION my_pg_lake_integration
  TYPE = POSTGRES_EXTERNAL_STORAGE
  STORAGE_PROVIDER = 'S3'
  ENABLED = TRUE
  STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/snowflake_pg_lake_role'
  STORAGE_ALLOWED_LOCATIONS = ('s3://my-bucket/my-prefix/');

其中:

  • my_pg_lake_integration 是您为存储集成选择的名称。

  • TYPE = POSTGRES_EXTERNAL_STORAGE 指定此集成用于 Snowflake Postgres。

  • STORAGE_AWS_ROLE_ARN 是您在以下步骤中记录的角色:第 3 步 ARN:创建 IAM 角色。

  • STORAGE_ALLOWED_LOCATIONS 指定 S3 桶和路径前缀。将 my-bucket 和 my-prefix 替换为您在 第 1 步:创建 S3 桶 中创建的桶名称和文件夹路径。请注意,Postgres 存储集成仅允许一个位置。

备注

创建存储集成需要拥有 ACCOUNTADMIN 角色,或在账户上拥有 CREATE INTEGRATION 权限的角色。有关更多信息,请参阅 访问控制权限。

第 5 步:检索 Snowflake IAM 用户 ARN 和外部 ID

创建存储集成后,使用 DESCRIBE INTEGRATION 命令检索 Snowflake 为此集成生成的 AWS IAM 用户和外部 ID:

DESCRIBE STORAGE INTEGRATION my_pg_lake_integration;

在输出中,找到并记录以下值:

  • STORAGE_AWS_IAM_USER_ARN:选择使用 时默认使用的角色和仓库。Snowflake 将用于承担该角色的 IAM 用户 ARN

  • STORAGE_AWS_EXTERNAL_ID:选择使用 时默认使用的角色和仓库。要在信任策略中使用的外部 ID

您将在下一步中使用这些值来配置 IAM 角色信任策略。

第 6 步:更新 IAM 角色信任策略

更新您在以下步骤中创建的 IAM 角色的信任策略:第 3 步:创建 IAM 角色,来允许 Snowflake 承担该角色:

  1. 登录 AWS 管理控制台并导航至 IAM 服务。

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

  3. 选择您在以下步骤中创建的角色:第 3 步创建 IAM 角色。

  4. 选择 Trust relationships 选项卡。

  5. 选择 Edit trust policy。

  6. 将策略文档替换为以下文本:

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

    将占位符值替换为您在 第 5 步:检索 Snowflake IAM 用户 ARN 和外部 ID 中记录的值:

    • 将 storage_aws_iam_user_arn 替换为 STORAGE_AWS_IAM_USER_ARN 值。这是一个格式为 arn:aws:iam::<account_id>:user/snowflake-postgres-integration-management 的完整 ARN,其中用户名始终相同,仅 AWS 账户 ID 有所不同。

    • 将 storage_aws_external_id 替换为 STORAGE_AWS_EXTERNAL_ID 值。

  7. 选择 Update policy 以保存费用。

第 7 步:将存储集成附加到 Postgres 实例

将该存储集成附加到您的 Snowflake Postgres 实例。附加存储集成后,S3 凭据将自动同步到 Postgres 控制平面,并供 pg_lake 使用:

ALTER POSTGRES INSTANCE my_postgres_instance
  SET STORAGE_INTEGRATION = my_pg_lake_integration;

您也可以在创建新的 Postgres 实例时指定存储集成:

CREATE POSTGRES INSTANCE my_postgres_instance
  ...
  STORAGE_INTEGRATION = my_pg_lake_integration;

要从 Postgres 实例中移除存储集成,请执行以下操作:

ALTER POSTGRES INSTANCE my_postgres_instance
  UNSET STORAGE_INTEGRATION;

第 8 步:配置并使用 pg_lake

附加存储集成后,连接到您的 Postgres 实例并配置 pg_lake。有关可用扩展的列表,请参阅 Snowflake Postgres 扩展。

  1. 创建 pg_lake 扩展:

    CREATE EXTENSION pg_lake CASCADE;
    
  2. 设置 Iceberg 表的默认存储位置。该位置应与您的存储集成中指定的位置匹配。

    SET 命令仅适用于当前会话:

    SET pg_lake_iceberg.default_location_prefix = 's3://my-bucket/my-prefix';
    

    要为当前和未来的所有会话设置该值,请改用 ALTER DATABASE 命令。如果您使用多个 Postgres 数据库,请确保为每个数据库分别设置存储位置:

    -- Substitute the name of your database
    ALTER DATABASE my_database SET pg_lake_iceberg.default_location_prefix = 's3://my-bucket/my-prefix';
    
  3. 通过列出 S3 桶的内容来验证存储集成是否配置正确:

    SELECT * FROM lake_file.list('s3://my-bucket/my-prefix/*');
    

    将 my-bucket 和 my-prefix 替换为您实际的桶名称和路径。如果配置正确,此查询将返回该位置的文件列表。如果桶为空,查询将返回空结果集且不报错。

  4. 通过创建 Iceberg 表、插入数据并回查数据,验证端到端配置。如果成功,说明 pg_lake 已具备对 S3 桶的读写能力:

    CREATE TABLE my_table (
        id INT,
        data TEXT
      ) USING iceberg;
    
    INSERT INTO my_table VALUES (1, 'hello iceberg');
    
    SELECT * FROM my_table;
    

安全注意事项

在为 pg_lake 配置 S3 访问权限时,请牢记以下安全最佳实践:

  • 使用 IAM 角色:Snowflake Postgres 使用 IAM 角色承担而非静态凭证,通过临时凭据和自动凭据轮换提供更高的安全性。

  • 限制 IAM 权限:仅向 pg_lake 需要访问的 S3 桶路径授予所需的最低权限。IAM 策略应限制对特定桶前缀的访问。

  • 监控外部 ID:信任策略中的外部 ID 可确保只有您的 Snowflake 账户能够承担 IAM 角色。

  • 审核存储集成变更:对存储集成的 STORAGE_AWS_ROLE_ARN 或 STORAGE_ALLOWED_LOCATIONS 进行的任何更新都会自动同步到 Postgres 实例。

  • 使用桶策略:除了 IAM 策略外,考虑使用 S3 桶策略以实现纵深防御。

  • 启用 S3 访问日志记录:在 S3 桶上启用访问日志记录,以监控和审计访问模式。

  • 区域一致性:确保您的 S3 桶与 Snowflake 账户位于同一 AWS 区域,以获得最佳性能并满足数据驻留要求。

故障排除

存储集成创建错误

如果在创建存储集成时遇到错误:

  • 验证您是否拥有 ACCOUNTADMIN 角色,或在账户上拥有 CREATE INTEGRATION 权限的角色。

  • 确保 IAM 角色 ARN 格式正确,且存在于您的 AWS 账户中。

  • 确认 S3 桶位置使用了正确的格式:s3://bucket-name/prefix/

  • 请注意,对于 POSTGRES_EXTERNAL_STORAGE 集成,仅允许设置一个存储位置。

小技巧

存储集成错误会记录在 Postgres 服务器日志中,并带有 Storage integration: 前缀。例如:

Storage integration: IAM role must have Maximum Session Duration set to 12 hours

有关访问 Postgres 日志的信息,请参阅 Snowflake Postgres 日志记录。

连接错误

如果附加存储集成后 pg_lake 无法访问 S3,请执行以下操作:

  • 通过查询实例属性,验证存储集成是否已正确附加到 Postgres 实例。

  • 检查 IAM 角色信任策略是否已使用 DESCRIBE STORAGE INTEGRATION 输出中的正确 Snowflake IAM 用户 ARN 和外部 ID 进行更新。

  • 确保 S3 桶区域与您的 Snowflake 账户区域匹配。

  • 验证您所在区域的 STS 端点在 AWS IAM 账户设置中处于活跃状态。

权限被拒绝错误

如果在访问 S3 时收到“权限被拒绝”错误,请执行以下操作:

  • 确认附加到角色的 IAM 策略包含所有必需权限:s3:PutObject、s3:GetObject、s3:GetObjectVersion、s3:DeleteObject、s3:DeleteObjectVersion、s3:ListBucket 和 s3:GetBucketLocation。

  • 验证 IAM 角色的信任策略是否允许 Snowflake IAM 用户承担该角色。

  • 检查 S3 桶策略(如有)是否拒绝了来自 IAM 角色的访问。

  • 确保您访问的 S3 路径与 STORAGE_ALLOWED_LOCATIONS 中指定的前缀匹配。

信任策略错误

如果遇到与承担 IAM 角色相关的错误,请执行以下操作:

  • 验证信任策略中的外部 ID 是否与存储集成中的 STORAGE_AWS_EXTERNAL_ID 完全匹配。

  • 确认信任策略中的主体 ARN 是否与存储集成中的 STORAGE_AWS_IAM_USER_ARN 匹配。

  • 检查 IAM 角色的最大会话持续时间是否已设置为 12 小时。