为 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_nameprefix 替换为您实际的桶名称和文件夹路径前缀:

    {
        "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-bucketmy-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-bucketmy-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_ARNSTORAGE_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:PutObjects3:GetObjects3:GetObjectVersions3:DeleteObjects3:DeleteObjectVersions3:ListBuckets3:GetBucketLocation

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

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

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

信任策略错误

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

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

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

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