亚马逊AWS官方博客

Snowflake on AWS 使用指南 – 通过 AWS PrivateLink 实现 Snowflake 数据仓库私有连接

前言

Snowflake 是一款云原生的全托管数据云服务平台,Snowflake 将全新的 SQL 查询引擎与专为云原生设计的创新架构相结合,无需安装、配置或维护硬件或软件。Snowflake 为用户提供了比传统产品更快、更易于使用且更灵活的数据存储、处理和分析解决方案。目前,Snowflake 数据云服务平台已正式上线亚马逊云科技中国宁夏区域。

云原生架构使 Snowflake 天然具备与众多亚马逊云服务的原生集成能力,如 AWS PrivateLink(需要 Snowflake 业务关键版(Business Critical Edition)及以上支持)。通过 AWS PrivateLink,客户可以将 AWS VPC 内部署的应用程序和服务轻松安全的通过私有 IP 地址与 Snowflake 云服务环境直接连接,进行数据库操作与 SQL 命令提交,还可以通过 AWS PrivateLink 连接 Snowflake Internal Stage(基于 Amazon S3 的内部数据暂存区)进行数据文件的上传/下载(PUT/GET),而无需具备访问公共互联网的能力(通过公有 IP 与互联网网关)。从而极大地降低潜在网络攻击与数据泄漏的风险,提高安全性、可管理性和运维效率。这对于一些数据敏感度高的行业如金融、医疗健康、汽车等至关重要。

在本文中,我们将详细演示如何通过配置 PrivateLink 连接 Snowflake 的云服务与内部存储区,包括如下三种不同场景:

  • 通过 Privatelink 连接 Snowflake 云服务层(Cloud Service)
  • 通过 PrivateLink 连接 Snowflake 内部存储区(Internal Stage)
  • 通过 PrivateLink 与 VPC Peering 进行跨区域连接

以及如何进行测试验证:

  • 验证 Snowflake 云服务(Cloud Service)访问
  • 验证 Snowflake 内部存储区(Internal Stage)访问

架构说明

如上图所示,Snowflake 与 AWS PrivateLink 的集成可分为 Cloud Service(云服务)层私有连接,和 Internal Stage(内部暂存区,基于 S3 的 Snowflake-managed 存储区域)的私有连接。使用者可以根据自身需要选择不同的连接方式组合。

连接层 组合 1 组合 2 组合 3 组合 4
Cloud Service
(云服务层)
Public
(公开)
Private
(私有)
Private
(私有)
Public
(公开)
Internal Stage
(内部数据暂存区)
Public
(公开)
Private
(私有)
Public
(公开)
Private
(私有)

在跨区域连接 Snowflake 时,需要结合 AWS PrivateLink 和 VPC Peering。例如,当应用系统部署在北京区域,而 Snowflake 在宁夏区域时,就需要这种组合方案。要注意的是,Snowflake 出于安全和租户管理考虑,不提供对外的直接 VPC Peering 连接。最佳实践是:在自己的 AWS 账号内建立跨区域的 VPC Peering 连接,然后使用 AWS PrivateLink 与 Snowflake 建立私有连接。这样可以实现跨区域的端到端私有通路,如下图所示:

先决条件

假设您已满足如下条件:

  • 拥有创建数据库、表、Internal Stage、External Stage 等权限的 Snowflake 账号;
  • 供测试使用的 Snowflake 表数据;
  • 具备相应操作权限的亚马逊云科技账号;
  • 安装了 AWS CLI 与 SnowSQL CLI(可选)的终端。

配置步骤

1. 通过 Privatelink 连接 Snowflake 云服务层(Cloud Service)

1.1 配置 Snowflake 账号 PrivateLink 访问授权

  • 打开命令行,执行 AWS configure,配置 AWS CLI,Region 建议选择 Snowflake 账号所在区域,这里我们以宁夏区域为例,权限设置可参考这里
    $ aws configure
    AWS Access Key ID []:< User Key ID>
    AWS Secret Access Key []: <Key Secret>
    Default region name []: cn-northwest-1
    Default output format [json]:
    
    PowerShell
  • 执行 AWS CLI STS get-federation-token 命令,生成临时 Token,并保存结果待后续使用;
    aws sts get-federation-token --name <federated user name>
    PowerShell

示例如下:

  • 登录 Snowflake 界面,打开 SQL Worksheet,执行如下语句切换执行角色为 accountadmin;
    use role accountadmin;
    PowerShell
  • 接着执行如下 select 语句,使用上一步中 AWS STS 命令返回的 FederatedUserId 与 Credentials 替换其中<aws_id>与<federated_token>值;
    select SYSTEM$AUTHORIZE_PRIVATELINK('<aws_id>','<federated_token>');
    PowerShell
  • 执行如下 SELECT 语句,查看 Snowflake 账号所提供的 Endpoint Service 名称,记录输出结果中”privatelink-account-url”, “privatelink-vpce-id”, “privatelink_ocsp-url”的对应值;
    select key, value from table(flatten(input=>parse_json(system$get_privatelink_config())));
    PowerShell

如果本地安装了 SnowSQL CLI,也可通过 SnowSQL 进行命令行的操作。这里不再做赘述。

1.2 创建 Endpoint(终端节点)

这里需要在 AWS 管理控制台中创建 Endpoint(终端节点),通过 Endpoint(终端节点)访问 Snowflake 的 Endpoint Service(终端节点服务)。

  • 打开 VPC 控制台,在左侧导航窗格中选择”Endpoint(终端节点)”;
  • 选择 Create Endpoint(创建终端节点);
  • 输入 Endpoint 名称(可选);
  • 在 Service Category(服务类别)中选择 Endpoint services that use NLBs and GWLBs(使用 NLB 和 GWLB 的端点服务);
  • 在 Service Settings(服务设置)中,输入第 1 步中查询到的 privatelink-vpce-id,并点击”Verify service(验证服务)”;
  • 待验证通过后,继续选择需要通过 AWS PrivateLink 连接 Snowflake 的 VPC,并选择 Endpoint(终端节点)部署的 Availability Zone(可用区)与 Subnet(子网),以及相应的安全组等信息;
  • 待 Endpoint(终端节点)创建完毕后,记录 Endpoint(终端节点)的 DNS names(DNS 名称);
  • 编辑 Endpoint(终端节点)的安全组规则:
    • 在 Endpoint 界面选中创建好的 Endpoint,点击页面下方的 Security Groups,选择 Inbound rules(入站规则),进行编辑;
    • 在入站规则中,添加对 HTTP/HTTPS 的入站控制条目,Source(源)指定为当前 VPC 的 CIDR,完成后保存退出。(注意:HTTP 与 HTTPS 都需要添加,此处的源 IP 地址可根据实际使用需要进行精细化设置);

完成 Endpoint 创建。

1.3 配置 Amazon Route 53

我们需要使用 Amazon Route 53 的私有 DNS 解析,将 VPC 中对 Snowflake 私有连接请求通过 DNS 解析到 Endpoint(终端节点)。

  • 打开 Amazon Route 53 的控制台,在左侧菜单栏中选择”Hosted zone(托管区域)”;
  • 选择”Create hosted zone(创建托管区)”;
  • 在”Domain name(域名)” 处输入标准值”privatelink.snowflakecomputing.cn”;
  • Type(类型)选择”Private hosted zone(私有托管区)”;
  • 在”VPCs to associate with the hosted zone(要与托管区关联的 VPC)” 选择当前 Region(区域)以及相应的 VPC,并点击创建;
  • 待创建完成后,在 Records(记录)页点击右上方的”Create record(创建记录)”,选择”Simple routing(简单路由)”,添加路由记录;
    • 输入此前第 1.1 步中保存的 private-account-url 中的<account_locator>.<cloud_region_id>部分;
    • 选择 Recored type(记录类型)为 CNAME;
    • 在”Value/Route Traffic to( 值/流量路由至 )” 中选择”IP address or another value(IP 地址或其他值)”;
    • 在地址框中输入此前 1.2 中创建的 Endpoint(终端节点)的 DNS names(DNS 名称);
  • 点击 Create records(创建记录)完成创建;
  • 相同步骤再创建针对 ocsp 的路由记录,CNAME 地址同样指向 Endpoint 的 DNS names(DNS 名称);
  • 最终结果如下所示:

至此,通过 AWS PrivateLink 访问 Snowflake 云服务的配置就完成了。

2. 通过 PrivateLink 连接 Snowflake 内部暂存区(Internal Stage)

2.1 启用 Internal Stage 私有连接设置

  • 首先我们在 Snowflake 中创建一个 internal stage:
    create or replace stage <stage_name>;
    PowerShell
  • 设置 ENABLE_INTERNAL_STAGES_PRIVATELINK 参数以启用对通过 AWS PrivateLink 连接到 Internal Stage 支持:
    alter account set ENABLE_INTERNAL_STAGES_PRIVATELINK = true;
    PowerShell
  • 执行如下 SELECT 命令,查看 Snowflake 账号所提供的 Endpoint Service 名称,找到”privatelink-internal-stage”行,记录对应取值;
    select key, value from table(flatten(input=>parse_json(system$get_privatelink_config())));
    PowerShell

2.2 配置 Endpoint(终端节点)

打开 AWS 管理控制台,将 Region(区域)切换到您的 Snowflake 账号所在的 AWS Region(区域)。这里需要在 AWS 管理控制台中创建 Endpoint for S3(终端节点),通过 Interface Endpoint(终端节点)访问 Snowflake 的 Internal Stage;

  • 打开 VPC 控制台,在左侧导航窗格中选择 Endpoint(终端节点);
  • 选择 Create Endpoint(创建终端节点);
  • 输入 Endpoint名称(可选);
  • 在 Service Category(服务类别)中选择 AWS Services(AWS 服务);
  • 在 Services(服务)中,选择 S3,类型为 Interface(Interface 与 Gateway 类型区别参考这里);
  • 根据实际情况选择 VPC、子网与安全组;
  • 点击 Create Endpoint(创建终端节点)进行创建,待 Endpoint(终端节点)创建完毕后,记录 Endpoint(终端节点)的 DNS names(DNS 名称);
  • 编辑 Endpoint(终端节点)的安全组规则:
    • 在 Endpoint 界面选中创建好的 Endpoint,点击页面下方的 Security Groups,打开安全组管理界面,编辑 Inbound rules(入站规则);
    • 在入站规则中,添加对 HTTPS 的入站控制条目,Source(源)指定为当前 VPC 的 CIDR,完成后保存退出(Interface Endpoint for S3 仅需添加 HTTPS 规则);

Endpoint 配置完毕。

2.3 配置 Amazon Route 53

同样,使用 Amazon Route 53 的私有 DNS 解析,将 VPC 中对 Snowflake 私有连接请求通过 DNS 解析到 Endpoint(终端节点)。

  • 打开 Amazon Route 53的控制台,在左侧菜单栏中选择“Hosted zone(托管区域);
  • 选择“Create hosted zone(创建托管区)” ;
  • 在”Domain name(域名)”处输入值”s3.cn-northwest-1.amazonaws.com.cn”(注:此处输入格式为<region>.amazonaws.com.cn,请按照实际区域替换<region>取值)
  • Type(类型)选择”Private hosted zone(私有托管区)”;
  • 在”VPCs to associate with the hosted zone(要与托管区关联的 VPC)” 选择当前 Region(区域)以及相应的 VPC,并点击创建;
  • 待创建完成后,在 Records(记录)页点击右上方的”Create record(创建记录)” ,选择”Simple routing(简单路由)”,接着添加路由记录;
    • 输入此前第 2.3 步在 Snowflake 中查询到的 privitelink-internal-stage 的 URL 前缀;
    • 选择 Recored type(记录类型)为 CNAME;
    • 在”Value/Route Traffic to( 值/流量路由至 )” 中选择”IP address or another value(IP 地址或其他值)”;
    • 将之前从 Snowflake 查询到的”privatelink-internal-stage”取值中 bucket-name 部分与创建好的 Endpoint DNS 名称合并,得到如下格式的 URL:
      dcc-xx-xxx-customer-stage.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.cn-northwest-1.vpce.amazonaws.com.cn
      PowerShell

      将该 URL 填入 CNAME 地址栏中

  • 完成创建,最终结果如下所示:

至此,通过 AWS PrivateLink 访问 Snowflake 的 Internal Stage 配置完成。

3. 通过 PrivateLink 与 VPC Peering 进行跨区域连接

跨区域连接是在创建好 PrivateLink 的基础上增加 VPC Peering 的部分,先按照上述步骤完成 PrivateLink Endpoint 配置。再进行 VPC Peering 设置,VPC Peering 的设置步骤可以参考这里

在跨区域的情况下,同样需要配置 Route 53 的 Private Hosted Zone(如上述步骤 7),但在创建时要注意区域和 VPC 的选择,以中国区为例,在北京区域的应用程序要跨区域访问位于宁夏区域中的 Snowflake,此时,Private Hosted Zone 的区域和 VPC 就应该选择北京区域以及相对应的 VPC。除此不同之外,其他配置与上述步骤说明保持相同即可。

另外,在配置好 VPC Peering 后,注意要在所创建的 Endpoint(端点)的安全组中,加入远端 VPC 的地址段,允许 HTTP 和 HTTPS 流量。

验证测试(可选)

接下来让我们使用 SnowSQL 测试验证私有连接的访问。

我们在 PrivateLink Endpoint 所在的 VPC 中开启一台 EC2,安装 SnowSQL 用以验证测试,请确保 SnowSQL 版本在 1.3.2 以上。

1. 验证 Snowflake云服务(Cloud Service)访问

1.1 首先通过默认的公共连接串测试访问

命令如下(通过 SnowSQL 连接):

snowsql -a <account_locator>.<cloud_region_id> -h <host> -u <username>
PowerShell

可以看到,SnowSQL 可以正常通过默认的公共连接串连接 Snowflake 服务,并能正常执行 SQL 查询语句。

1.2 再测试通过 Snowflake 的 PrivateLink 连接串的访问

如下图所示,同样可以正常访问,命令如下:

snowsql -a <account_locator>.<cloud_region_id> -h <host with privatelink> -u <username>
PowerShell

1.3 在 Snowflake 中创建两条 Network Rule(网络规则),关闭 Snowflake 的公开访问权限,仅允许 PrivateLink 访问,并创建一个包含这两条规则的网络策略

CREATE NETWORK RULE block_public_access
	MODE = INGRESS
	TYPE = IPV4
	VALUE_LIST = ('0.0.0.0/0');

CREATE NETWORK RULE allow_vpceid_access
	MODE = INGRESS
	TYPE = AWSVPCEID
	VALUE_LIST = ('<vpce-id>');

CREATE NETWORK POLICY allow_vpceid_block_public_policy
	ALLOWED_NETWORK_RULE_LIST = ('allow_vpceid_access')
	BLOCKED_NETWORK_RULE_LIST = ('block_public_access');
PowerShell

1.4 执行如下命令,激活网络策略

注意:因为我们要激活的规则是仅允许 AWS PrivateLink 连接。所以,我们需要先通过 AWS PrivateLink 的方式连接到 Snowflake 中,再执行激活命令,否则会执行不成功。

ALTER ACCOUNT SET NETWORK_POLICY = allow_vpceid_block_public_policy;
PowerShell

1.5 新的 network policy 被成功激活,现在我们退出当前的 PrivateLink 连接,改用公共连接串尝试登录

这里我们能看到通过公共连接串登录会被拒绝,在报错中能够详细的看到请求的 IP 地址被阻止访问:

1.6 修改为私有连接串,能够正常登录与操作

这说明我们当前与 Snowflake 云服务层的连接是通过 AWS PrivateLink 链路实现:

1.7 执行如下命令将 network policy 取消激活

ALTER ACCOUNT SET NETWORK_POLICY = '';
PowerShell

2. 验证Snowflake内部存储区(Internal Stage)访问

2.1 从客户端机器执行以下命令,以验证返回的 IP 地址是 Interface Endpoint for S3 的私有 IP 地址

dig <bucket_name>.s3.<region>.amazonaws.com.cn
PowerShell

将<bucket_name>替换为本例中的”dcc-xxx-xxx-customer-stage”,<region>替换为本例中”cn-northwest-1″,结果如下:

查看 Endpoint(端点)中的 IP 地址,符合解析结果。

到这里已经可以确定 Internal Stage 的私有访问是正确配置的。接下来我们使用 SnowSQL 做进一步的验证。

2.2 在客户端机器上准备两个 csv 文件(data1.csv、data2.csv),通过 SnowSQL 登录 Snowflake,执行 put 命令尝试将 data1.csv 文件上传至已创建的 Internal Stage 中

put file:///home/ec2-user/data1.csv @my_internal_stage_cn_northwest_1;
PowerShell

上传成功。

2.3 删除 Amazon Route 53 中 s3.cn-northwest-1.amazonaws.com.cn 私有托管区域中定义的 CNAME 记录

结果如下:

2.4 回到 SnowSQL 界面,同样使用 put 命令尝试上传 data2.csv 文件

put file:///home/ec2-user/data2.csv @my_internal_stage_cn_northwest_1;
PowerShell

此时上传失败。这是因为当启用了 ENABLE_INTERNAL_STAGES_PRIVATELINK 参数后,Snowflake Internal Stage 只允许来自 AWS PrivateLink 连接,而删除 Route 53 中的 CNAME 解析导致客户端依然使用公开地址访问 Internal Stage 的 S3 桶,所以无法成功连接。

2.5 执行 alter 命令禁用 ENABLE_INTERNAL_STAGES_PRIVATELINK 参数,以关闭对通过 AWS PrivateLink 连接到 Internal Stage 的设置,恢复为默认使用公开地址连接

alter account set ENABLE_INTERNAL_STAGES_PRIVATELINK = false;
PowerShell

2.6 再次执行 put 命令上传 data2.csv 文件,上传成功

至此,配置与验证工作全部结束。

总结

通过以上的内容,我们完整地展示了 Snowflake 与 AWS PrivateLink 的集成过程与能力,以及如何结合 VPC Peering 实现跨区域访问。在解决私有连接访问的基础上,还可以进一步通过 Snowflake 的 Network Rule(网络规则)与 Policy(策略)设定,以及在 AWS 中安全组控制等能力实现细粒度的安全管控,从而满足企业客户在安全性、合规性等方面的多样化要求。

参考资料

1. Snowflake 中国(宁夏)区域说明:https://docs.snowflake.com/en/user-guide/intro-regions#asia-pacific-china

2. AWS PrivateLink and Snowflake:https://docs.snowflake.cn/en/user-guide/admin-security-privatelink

3. 适用于内部暂存区的 AWS VPC 接口端点:https://docs.snowflake.cn/en/user-guide/private-internal-stages-aws

4. 使用网络策略控制网络流量:https://docs.snowflake.cn/en/user-guide/network-policies

5. AWS PrivateLink 用户指南:https://docs.amazonaws.cn/en_us/vpc/latest/privatelink/what-is-privatelink.html

6. AWS VPC Peering用户指南:https://docs.amazonaws.cn/vpc/latest/peering/what-is-vpc-peering.html

本篇作者

孙大山

亚马逊云科技解决方案架构师,目前负责 ISV 领域相关客户云端架构设计与技术咨询,拥有 20 年数据领域和公有云行业技术售前与解决方案构建经验。对数据库、数据分析、数据治理、数字化转型有丰富的探索与实践。

席叶文

Snowflake 高级数据云架构师,在科技行业拥有十余年的丰富经验。凭借在公共云和领先网络公司的背景,和在云计算、网络和数据解决方案方面拥有深厚的专业知识,为现代企业打造创新可靠的架构。