亚马逊云科技 AppSync 私有 API 的架构模式

亚马逊云科技 AppSync 是一项完全托管的服务,它使开发人员能够创建 GraphQL API,以安全地访问、操作和合并来自一个或多个数据源的数据。最近,亚马逊云科技宣布支持 亚马逊云科技 AppSync私有API , 以帮助客户限制私有网络(例如 亚马逊虚拟私有云 (VPC) 或混合环境)中的API使用者访问您的GraphQL API。对 AppSync 私有 API 的请求将通过 亚马逊云科技 的私有网络传输,无需通过互联网。来自您的应用程序的 GraphQL 请求通过接口 VPC 终端节点路由到 亚马逊云科技 AppSync。接口 VPC 终端节点由 亚马逊云科技 Pri v ateLink 提供支持,这是一种高度可用、可扩展的技术,使您能够将您的 VPC 私密连接到 亚马逊云科技 AppSync 等服务,就好像这些服务位于您的 VPC 中一样。

使用私有 API,您的私有网络中的消费者无需通往互联网的路由即可与 API 端点通信。在这篇博客中,我们将介绍五种常见的架构模式,以建立与您的 亚马逊云科技 AppSync 私有 API 的连接。这些架构模式包括:

  1. 通过 VPC 连接到 AppSync 私有 API
  2. 通过 VPC 连接到 AppSync 私有 API
  3. 跨账户连接到 AppSync 私有 API
  4. 与 AppSync 私有 API 的混合连接
  5. 使用 API 网关代理 AppSync 私有 API

AppSync 私有 API 可通过接口 VPC 端点 DNS 名称或 AppSync API GraphQL 终端节点(如果在创建 VPC 端点时启用了 “私有 DNS 名称”)进行访问,如下所示。

AWS AppSync Interface VPC Endpoint configuration

图 1:亚马逊云科技 AppSync 接口 VPC 终端节点配置

在以下部分中,我们将介绍每种架构模式,并解释如何设置架构以满足您的用例。我们将解释 API 使用者使用 AppSync API GraphQL 端点或接口 VPC 端点公有 DNS 主机名调用 API 端点所需的配置。

模式 1:与 AppSync 私有 API 的单个 VPC 连接
在这种模式 中,有两个 API 使用者(EC2 实例)托管在与 AppSync 接口终端节点相同的 VPC 中,如下所示。

Single VPC connectivity to AppSync Private APIs

图 2:与 AppSync 私有 API 的单个 VPC 连接

在 VPC 的 CIDR 范围内为 API 使用者和接口终端节点分配私有 IP 地址。默认情况下,每个路由表都包含用于在 VPC CIDR 内进行通信的本地路由。接口 VPC 端点 DNS 名称和 AppSync API GraphQL 端点(启用私有 DNS 名称)将解析为 亚马逊云科技 AppSync 接口端点的私有 IP 地址。这将确保对私有 API 的请求通过接口端点路由到 AppSync 私有 API。

模式 2:跨 VPC 连接到 AppSync 私有 API
在这种模式 中,API 使用者托管在与托管 AppSync VPC 接口终端节点的 VPC 分开的 VPC 中,位于同一 亚马逊云科技 账户中,两个 VPC 位于相同或不同的 亚马逊云科技 区域。您可以使用此模式通过单个 VPC 集中访问您的 AppSync 私有 API,这有助于简化 API 的安全性和访问要求。但是,重要的是要从成本和安全的角度比较集中式和分散式接口端点的设计,正如本次re: Invent演讲、 VPC端点和PrivateLink:针对安全性、成本和运营进行优化

Cross VPC connectivity to AppSync Private APIs

图 3:通过 VPC 连接到 AppSync 私有 API

要开始使用这种模式,请在一个 VPC(集中式 VPC)中创建 AppSync 接口终端节点,然后使用 VPC 对 等连接 或 亚马逊云科技 Transit Gat eway 连接这两个 V PC, 如上图所示。这将确保 VPC A 中的 API 使用者 可以到达 VP C B 中的 AppSync 接口终端节点。

如果您使用 AppSync 接口终端节点 DNS 名称来调用 AppSync 私有 API,则 VPC A 中的 API 使用者 无需任何其他配置 即可通过 VPC B 中的 AppSync 接口 VPC 终端节点访问私有 API。

使用 AppSync API GraphQL 端点调用私有 API 需要以下配置:

  • 关闭 VPC B 中的 “私有 DNS 名称”。这将删除将 AppSync 服务域名的请求解析为 AppSync 接口端点创建的弹性网络接口 (ENI) 的私有 IP 地址的 DNS 条目。
  • 创建 亚马逊 Route 53 私有托管区域 (PHZ),将域设置为 AppSync 服务域 appsync-api。{区域} .amazonaws.com 其中区域设置为 托管 AppSync 接口终端节点的 VPC B 区域。在创建 PHZ 时,将 VPC A VPC B 与托管区域相关联,您可以在 亚马逊云科技 账户内的任何区域中选择任意 VPC。将 VPC 关联到 PHZ 将确保使用 PHZ 中的 DNS 条目解析对 AppSync 服务域的任何请求。
    <li style="list-style-type: none"></li>

Create Private Hosted Zone

图 4:创建私有托管区域

  • 创建 PHZ 后,创建别名 DNS 记录,其名称设置为 AppSync API GraphQL 端点标识符 ( {api_url_identifient} .appsync- ap i。{区域} .amazonaws.com/graphql )和目标设置为 AppSync 接口终端节点,如下所示。有了这些设置,可以 使用 AppSync API GraphQL 终端节点从 VPC A 或 V PC B 调用 AppSync 私有 API。

Create hosted zone DNS records

图 5:创建托管区域 DNS 记录

模式 3:与 AppSync 私有 API 的跨账户连接
在这种模式 中,API 使用者托管在与托管 亚马逊云科技 AppSync 接口终端节点(账户 B)不同的 亚马逊云科技 账户(账户 A)中,两个 VPC 位于相同或不同的 亚马逊云科技 区域。在此用例中,您将工作负载分成不同的 亚马逊云科技 账户,使用一个专用账户作为 API 账户(账户 B)。对 AppSync 私有 API 的请求必须通过 API 账户中的 AppSync 接口端点路由到 AppSync 服务。

Cross Account connectivity to AppSync Private APIs

图 6:与 AppSync 私有 API 的跨账户连接

模式 2 类似 ,在其中一个 亚马逊云科技 账户中创建一个 AppSync 接口 VPC 终端节点,然后使用 VPC 对等连接或 亚马逊云科技 Transit Gateway 连接这两个 VPC,如上图所示。这将确保 VPC A 中的 API 使用者 可以到达 VP C B 中的 AppSync 接口终端节点。

使用 AppSync 接口终端节点 DNS 名称调用 API, VPC A 中的 API 使用者无需任何其他配置 即可访问私有 API。但是,如果您使用的是 AppSync API GraphQL 端点,则需要按照上面 模式 2 中说明的步骤进行操作。唯一的区别是 VPC 与 PHZ 的关联,这只能通过 CLI 或 SDK 来完成。以下是您需要在 CLI(例如 CloudShell)中完成的步骤,才能将 VPC A 关联 到 PHZ。

  1. 账户 B 中打开 CloudShell 终端节点与托管 AppSync 接口终端节点的 VPC 位于同一区域,然后运行以下命令列出可用的托管区域。记下您要与账户 A 关联的 账户 B 中的托管区域 ID。
    
    $ aws route53 列表
    托管区域
  2. 账户 B 中的 VPC B 所在区域的 CloudShell 终端 中运行以下命令。 此命令授权 账户 B 中的 PHZ 与账户 A 中的 VPC 之间的关联。 使用上一步中的托管区域 ID、 账户 A 中的 亚马逊云科技 区域和该 VPC 的 ID。
    
    $ aws route53 create-vpc-association-authorization--hosted-zone-id [hosted-zone-id]--vpc vpcRegion= [region],vpcid= [vpc-id] 
     
    
  3. 账户 A 中打开 CloudShell 终端 并运行以下命令。此命令创建 账户 B 中的 PHZ 和账户 A 中的 VPC 之间的关联。 使用步骤 1 中的托管区域 ID、 账户 A 中的 VP C A 的区域和 VPC ID 。
    
    $ aws route53 associate-vpc-with-hosted-zone-zone-id [托管区域 ID]--vpc vpcregion= [区域],vpcid= [vpc-id] 
     
    
  4. PHZ 与 VPC 关联并传播更改可能需要几分钟。还建议您在使用此命令创建关联后删除关联。
    
    $ aws route53 delete-vpc-association-authorization--hosted-zone-id [hosted-zone-id]--vpc vpcRegion= [region],vpcid= [vpc-id] 
     
    
  5. 账户 B 的 Route 53 控制台中 ,选择 PHZ 并验证 账户 A 的 VPC ID 是否与 PHZ 相关联

VPC A 与 PHZ 关联后,按照 模式 2 中的步骤 3 中的说明创建别名 DNS 记录 ,这将完成配置。现在,你可以 使用 AppSync API GraphQL 终端节点从 VPC A 或 V PC B 上调用 AppSync 上的私有 API。

模式 4:与 AppSync 私有 API 的混合连接
在此架构中,采用混合架构,将 API 使用者托管在本地。例如,这些应用程序可以是尚未迁移到 亚马逊云科技 的应用程序,也可以是由于监管或合规要求而需要保留在本地的应用程序。

Hybrid connectivity to AppSync Private APIs

图 7 与 AppSync 私有 API 的混合连接

这种架构模式需要在 亚马逊云科技 和本地站点 之间建立 混合连接 。请参阅有关使用 亚马逊云科技 虚拟专用网络 (VPN) 或 亚马逊云科技 Di rect Connect 建立混合连接 的文档 。在 亚马逊云科技 VPC 和混合网络之间建立网络连接后,执行以下配置,让 API 使用者使用 AppSync 接口 VPC 终端节点 DNS 或 AppSync GraphQL 终端节点调用 AppSync 私有 API:

  • 确保 AppSync 接口端点的 “私有 DNS 名称” 已启用。这将确保发往 AppSync GraphQL 端点的请求通过 AppSync 接口端点路由到 AppSync 私有 API
  • 为托管 AppSync 接口端点的 VPC 创建 Amazon Route 53 解析器入站终端节点。您可以按照 文档 获取有关如何创建入站端点的分步指南。您将需要: 为解析器
    • 入站终端节点 指定名称指定用于部署解析器入
    • 站终端节点的 VPC 提供用于终端节点
    • 的安全组 指定两个或更多可用区域和子网,从中为解析器入站终
    • 端节点分配 IP 地址以进行
    DNS 查询

Configure Route 53 resolver for inbound-endpoints

图 8:为入站端点配置 Route 53 解析器

  • 在本地环境中,更新 DNS 服务器以将请求转发到 AppSync 接口端点 DNS (appsync- api)。{区域} .vpce.amazonaws.com )和 AppSync 服务域名(appsync-api。 {区域} .amazonaws.com ) 到解析器入站终端节点 IP 地址。使用这些设置,来自本地环境中 API 使用者的 GraphQL 请求将到达 AppSync 接口端点。

模式 5:带有 API 网关的代理 AppSync 私有 API
此模式解决了使用 亚马逊 API Gat eway 的功能来控制对 AppSync 私有 API 访问权限的用例。API Gateway 将充当代理,将 GraphQL 请求转发到 AppSync 私有 API。

注意 :此架构模式只能与 AppSync 私有 API 一起使用。如果您的 AppSync API 具有公共端点,请将 API 网关 API 集成 (采用 HTTP 集成 类型)设置为代理向 AppSync GraphQL 端点发出的请求。

Proxy AppSync Private APIs with API Gateway

图 9 带有 API 网关的代理 AppSync 私有 API

在这种模式下,AppSync 私有 API 通过网络负载均衡器公开,然后通过 VPC 链接代理到 API 网关。 VPC 链接的作用与 API 的任何其他集成端点类似,是其他网络资源之上的抽象层。以下四个步骤配置此架构:

  1. 在 AppSync 上创建您的私有 API,并在目标子网上部署 亚马逊云科技 AppSync 接口终端节点。
  2. 创建网络负载均衡器,将目标设置为 亚马逊云科技 AppSync 接口终端节点的 IP 地址。
  3. 使用网络负载均衡器作为目标服务创建 VPC 链接、REST API 和私有集成(请参阅 此处 有关如何创建这些资源的指南)。
  4. 您可以在 API Gateway 上将您的 API 设置为私有、区域或边缘优化 API。在上面的架构图中,我们展示了 API 网关上的区域 API 的设置。

通过这种设置,有权访问 API 网关端点的 API 使用者将能够在 AppSync 上调用私有 API。您可以在 github 上部署示例 CDK 应用程序 ,该应用程序将使用样例 AppSync 私有 API 来测试设置来创建区域 API 网关端点。

在 AppSync 私有 API 上调用 GraphQL 操作(查询、突变和订阅)调用 AppSync 私 有 API
有两种方法:


  • 使用格式为 https://{api_url_identifier}.appsync-api 的 AppSync GraphQL 端点(由 AppSync 生成)。 {区域}. amazonaws.com/graphql

  • 使用 AppSync 接口端点 DNS(这是为 AppSync 接口端点生成的,格式为 https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api。{区域} .vpce. amazonaws.com/graphql

对于希望在调用私有 API 和非私有 API 时保持相同应用程序配置的客户,建议使用 AppSync GraphQL 端点。但是,如果在某些用例中,API 使用者需要从 VPC 调用私有 API 和非私有 API,则需要在非私有 API 上配置 AppSync 自定义 域,并使用自定义域调用非私有 API。这是因为开启私有 DNS 的 AWS AppSync 接口终端节点会将所有流量路由到目标 *.appsync-api。{区域} .amazonaws.com/graphql 通过 亚马逊云科技 AppSync 的 接口终端节点,非私有 API 将被屏蔽。

使用 AppSync 接口端点 DNS,可以将 API 使用者配置为调用 AppSync 私有 API,这将通过接口端点路由流量。使用 AppSync 接口端点 DNS 时,可以在接口端点上关闭 “私有 DNS 名称”。API 使用者可以使用 API AppSync GraphQL 端点调用其他非 AppSync 私有 API,无需配置 AppSync 自定义域。

要使用 AppSync GraphQL 端点调用您的私有 API 进行查询和突变,请参阅以下示例

$ curl -v https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ 
-H "Content-Type:application/graphql" \ 
-H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ 
-d '{"query": "query listTodos {listTodos {items {id title description priority}}}","variables":"{}"}'

而且你可以使用 GraphQL 实时端点设置订阅,例如以下用于建立 websocket 连接的命令:

$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 -w0`
$ wscat -p 13 -s graphql-ws -c "wss://{api_url_identifier}.appsync-realtime-api.{region}.amazonaws.com/graphql?header=$header&payload=e30="

以下示例显示如何使用 AppSync 接口终端节点 DNS 调用私有 API 进行查询和突变。您需要将 AppSync GraphQL 端点设置为请求的主机或 x-appsync 域标头。

$ curl -v https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \
-H "Host:{api_url_identifier}.appsync-api.{region}.amazonaws.com" \
-d '{"query": "query listTodos {listTodos {items {id title description priority}}}","variables":"{}"}'

并且你可以使用 AppSync 接口终端节点 DNS 设置订阅,如以下示例所示,

$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 -w0`
$ wscat -H "X-AppSync-Domain:{api_url_identifier}.appsync-realtime-api.{region}.amazonaws.com" -p 13 -s graphql-ws -c "wss://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql?header=$header&payload=e30="

结论

在这篇博客中,我们介绍了访问您的 亚马逊云科技 AppSync 私有 API 的五种架构模式。这些模式将帮助您识别 API 使用者的架构和配置,以便安全地访问您的私有 API。您还可以将其中两种或更多种架构模式组合成一个架构,以满足不同位置的 API 使用者的需求。有关更多详细信息,请参阅 亚马逊云科技 AppSync 文档 中的 使用 亚马逊云科技 AppSync 私有 API

作者简介

Ozioma Uzoegwu

Ozioma 是亚马逊网络服务的首席解决方案架构师。在他的职位上,他通过提供架构指导和最佳实践,帮助各种规模的客户在 亚马逊云科技 云平台上实现转型和现代化。Ozioma 在网络开发、架构、云和 IT 管理方面拥有多年的经验。在加入 亚马逊云科技 之前,Ozioma 曾与 亚马逊云科技 高级咨询合作伙伴合作,担任 亚马逊云科技 业务的首席架构师。他热衷于软件开发,对使用无服务器技术构建现代应用程序有着浓厚的兴趣。

Kirankumar Chandrashekar K irankumar

是 亚马逊云科技 战略账户高级解决方案架构师。他专注于在架构 DevOps、使用无服务器实现现代化、容器和 Docker、ECS、EKS 等容器编排技术方面的领先客户。Kirankumar 热衷于 DevOps、基础设施即代码、现代化和解决复杂的客户问题。他喜欢音乐,也喜欢烹饪和旅行。