使用 Amazon AppSync 私有 API
如果使用 Amazon Virtual Private Cloud (Amazon VPC),您可以创建 Amazon AppSync 私有 API,只能从 VPC 中访问这些 API。通过使用私有 API,您可以限制对内部应用程序的 API 访问并连接到 GraphQL 和实时终端节点,而不会公开暴露数据。
要在您的 VPC 和 Amazon AppSync 服务之间建立私有连接,您必须创建一个接口 VPC 终端节点。接口终端节点由 Amazon PrivateLink

在启用私有 API 功能之前,需要考虑一些其他因素:
-
通过为启用了私有 DNS 功能的 Amazon AppSync 设置 VPC 接口终端节点,将禁止 VPC 中的资源使用 Amazon AppSync 生成的 API URL 调用其他 Amazon AppSync 公有 API。这是因为对公有 API 的请求是通过接口终端节点路由的,而公有 API 不允许这样做。要在该场景中调用公有 API,建议在公有 API 上配置自定义域名,VPC 中的资源可以使用这些域名调用公有 API。
-
您的 Amazon AppSync 私有 API 只能从您的 VPC 中使用。只有在您的浏览器的网络配置可以将流量路由到您的 VPC(例如,通过 VPN 或 Amazon Direct Connect 连接)时,Amazon AppSync 控制台查询编辑器才能够访问您的 API。
-
通过使用 Amazon AppSync 的 VPC 接口终端节点,您可以访问同一 Amazon 账户和区域中的任何私有 API。要进一步限制对私有 API 的访问,您可以考虑使用以下选项:
-
确保仅所需的管理员可以为 Amazon AppSync 创建 VPC 终端节点接口。
-
使用 VPC 终端节点自定义策略限制可以从 VPC 中的资源调用哪些 API。
-
对于 VPC 中的资源,我们建议您使用 IAM 授权调用 Amazon AppSync API,以确保为资源分配 API 的范围缩小角色。
-
-
在创建或使用限制 IAM 主体的策略时,您必须将方法的
authorizationType
设置为AWS_IAM
或NONE
。
创建 Amazon AppSync 私有 API
以下步骤说明了如何在 Amazon AppSync 服务中创建私有 API。
警告
您只能在创建 API 期间启用私有 API 功能。在创建 Amazon AppSync API 或 Amazon AppSync 私有 API 后,无法在这些 API 上修改该设置。
-
登录到 Amazon Web Services Management Console,然后打开 AppSync 控制台
。 -
在控制面板中,选择创建 API。
-
-
选择从头开始设计 API,然后选择下一步。
-
在私有 API 部分中,选择使用私有 API 功能。
-
配置其余选项,检查您的 API 的数据,然后选择创建。
您必须先在 VPC 中为 Amazon AppSync 配置一个接口终端节点,然后才能使用 Amazon AppSync 私有 API。请注意,私有 API 和 VPC 必须位于同一 Amazon 账户和区域中。
为 Amazon AppSync 创建接口终端节点
您可以使用 Amazon VPC 控制台或 Amazon Command Line Interface (Amazon CLI) 为 Amazon AppSync 创建接口终端节点。有关更多信息,请参阅《Amazon VPC 用户指南》中的创建接口端点。
要使用私有 DNS 选项,您必须设置 VPC 的 enableDnsHostnames
和 enableDnsSupportattributes
值。有关更多信息,请参阅《Amazon VPC 用户指南》中的查看和更新 VPC 的 DNS 支持。如果您为接口终端节点启用私有 DNS 功能,您可以使用其默认公有 DNS 终端节点向 Amazon AppSync API GraphQL 和实时终端节点发出请求(使用以下格式):
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
有关服务终端节点的更多信息,请参阅 Amazon General Reference 中的 Service endpoints and quotas。
有关与服务接口终端节点的交互的更多信息,请参阅《Amazon VPC 用户指南》中的使用接口 VPC 端点访问服务。
有关使用 Amazon CloudFormation 创建和配置终端节点的信息,请参阅 Amazon CloudFormation User Guide 中的 Amazon::EC2::VPCEndpoint。
高级 示例
如果您为接口终端节点启用私有 DNS 功能,您可以使用其默认公有 DNS 终端节点向 Amazon AppSync API GraphQL 和实时终端节点发出请求(使用以下格式):
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
在使用接口 VPC 终端节点公有 DNS 主机名时,调用 API 的基本 URL 将采用以下格式:
https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql
如果已在可用区中部署终端节点,您也可以使用可用区特定的 DNS 主机名:
https://{vpc_endpoint_id}-{endpoint_dns_identifier}-{az_id}.appsync-api.{region}.vpce.amazonaws.com/graphql.
使用 VPC 终端节点公有 DNS 名称需要将 Amazon AppSync API 终端节点主机名作为 Host
或 x-appsync-domain
标头传递给请求。这些示例使用在启动示例架构指南中创建的 TodoAPI
:
curl 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":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
在以下示例中,我们使用在启动示例架构指南中生成的 Todo 应用程序。为了测试示例 Todo API,我们将使用私有 DNS 调用该 API。您可以使用所选的任何命令行工具;该示例使用 curl{ }
) 中的值替换为您的 Amazon 账户中的相应值。
测试变更操作 - createTodo
请求
curl https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -d '{"query":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
测试变更操作 - createTodo
响应
{ "data": { "createTodo": { "id": "<todo-id>", "name": "My first GraphQL task", "where": "Day 1", "when": "Friday Night", "description": "Learn more about GraphQL" } } }
测试查询操作 - listTodos
请求
curl 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 {\n listTodos {\n items {\n description\n id\n name\n when\n where\n }\n }\n}\n","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
测试查询操作 - listTodos
请求
{ "data": { "listTodos": { "items": [ { "description": "Learn more about GraphQL", "id": "<todo-id>", "name": "My first GraphQL task", "when": "Friday night", "where": "Day 1" } ] } } }
测试订阅操作 - 订阅 createTodo
变更
要在 Amazon AppSync 中设置 GraphQL 订阅,请参阅构建实时 WebSocket 客户端。从 VPC 上的 Amazon EC2 实例中,您可以使用 wscatAPI
KEY
进行授权。
$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 | tr -d '\n'` $ wscat -p 13 -s graphql-ws -c "wss://{api_url_identifier}.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=$header&payload=e30=" Connected (press CTRL+C to quit) > {"type": "connection_init"} < {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}} < {"type":"ka"} > {"id":"f7a49717","payload":{"data":"{\"query\":\"subscription onCreateTodo {onCreateTodo {description id name where when}}\",\"variables\":{}}","extensions":{"authorization":{"x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}","host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com"}}},"type":"start"} < {"id":"f7a49717","type":"start_ack"}
或者,使用 VPC 终端节点域名,同时确保在 wscat
命令中指定 Host 标头以建立 WebSocket 连接:
$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 | tr -d '\n'` $ wscat -p 13 -s graphql-ws -c "wss://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql?header=$header&payload=e30=" --header Host:{api_url_identifier}.appsync-realtime-api.us-west-2.amazonaws.com Connected (press CTRL+C to quit) > {"type": "connection_init"} < {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}} < {"type":"ka"} > {"id":"f7a49717","payload":{"data":"{\"query\":\"subscription onCreateTodo {onCreateTodo {description id priority title}}\",\"variables\":{}}","extensions":{"authorization":{"x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}","host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com"}}},"type":"start"} < {"id":"f7a49717","type":"start_ack"}
运行下面的变更代码:
curl https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -d '{"query":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
然后,将触发订阅并显示消息通知,如下所示:
< {"id":"f7a49717","type":"data","payload":{"data":{"onCreateTodo":{"description":"Go to the shops","id":"169ce516-b7e8-4a6a-88c1-ab840184359f","priority":5,"title":"Go to the shops"}}}}
使用 IAM 策略限制创建公有 API
Amazon AppSync支持将 IAM Condition
语句与私有 API 一起使用。可以在 appsync:CreateGraphqlApi
操作的 IAM 策略语句中包含 visibility
字段,以控制哪些 IAM 角色和用户可以创建私有和公有 API。这样,IAM 管理员就能够定义仅允许用户创建私有 GraphQL API 的 IAM 策略。尝试创建公有 API 的用户将收到“未经授权”消息。
例如,IAM 管理员可以创建以下 IAM 策略语句以允许创建私有 API:
{ "Sid": "AllowPrivateAppSyncApis", "Effect": "Allow", "Action": "appsync:CreateGraphqlApi", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "appsync:Visibility": "PRIVATE" } } }
IAM 管理员还可以添加以下服务控制策略,以阻止 Amazon 组织中的所有用户创建私有 API 以外的 Amazon AppSync API:
{ "Sid": "BlockNonPrivateAppSyncApis", "Effect": "Deny", "Action": "appsync:CreateGraphqlApi", "Resource": "*", "Condition": { "ForAnyValue:StringNotEquals": { "appsync:Visibility": "PRIVATE" } } }