Front-End Web & Mobile
Introducing Private APIs on AWS AppSync
AWS AppSync is a fully managed service that enables developers to create GraphQL APIs that can securely access, manipulate and combine data from one or more data sources. When you create a GraphQL API on AppSync, a public endpoint will be generated which can be used to send queries, mutations and subscriptions requests to the API. However, clients within a private network, like an Amazon Virtual Private Cloud (VPC) or on-premises network, will need a network route through the internet to reach the AppSync public endpoint. This can be a challenge for customers that need to change their security policy and firewall rules to send requests to the AppSync API.
Today, we are announcing the general availability of AppSync Private APIs. With Private APIs, you can restrict access to your GraphQL APIs to clients within a private network, such as a VPC or on-premises data center. Requests to your Private API will go through AWS’s private network without going over the internet. To get started, you can set your API as private when creating your GraphQL API on AppSync and attach an interface VPC endpoint in each of the VPCs in the same AWS account from where you will be invoking the API. You can also use AWS Direct Connect or AWS Site to Site VPN to establish a private connection from your on-premises network to the VPC hosting the interface endpoint. With this connection, clients in your on-premises data center can invoke the Private API.
The diagram below shows how you can connect to your Private API on AWS AppSync from an application running in a VPC. In this example, I have used Amazon Elastic Compute Cloud (EC2) as the compute platform from where the API will be invoked; the architecture will have a similar configuration if other compute platforms like AWS Lambda or AWS Fargate are used to invoke the API. GraphQL requests from your application will be routed via the interface endpoint to AWS AppSync. The interface endpoint uses AWS PrivateLink, a highly available, scalable technology that enables you to privately connect your VPC to services like AWS AppSync (and other AWS and third party services) as if they were in your VPC. It can be deployed in any of the subnets in your VPC and it is recommended to deploy at least one endpoint in each availability zone (AZ) to ensure high availability.
Figure 1: High level architecture for connecting to AppSync Private API from Amazon VPC
Creating and connecting to your AppSync Private API
In this section, we will create a Private API on AWS AppSync and then invoke the API from an EC2 instance running in a VPC. We will be doing the following:
- create a simple Todo API with the API set as private
- create a VPC spread across two availability zones (AZs) with public and private subnets in each AZ
- attach an interface endpoint for AWS AppSync to the VPC private subnets
- invoke the API from EC2 instances deployed in the private subnets
Creating an AppSync Private API
- Navigate to the AppSync console and click on
Create API
- In Step 1 of the API creation wizard select
Design from scratch
and clickNext
. Note: You can also create a Private API while creating a new API from an existing DynamoDB table or creating a real-time API.
- In Step 2, provide a name for the API and select the checkbox
Use private API features
in the Private API section and click Next. Selecting this checkbox will make your API private.
- In Step 3 under
Create a GraphQL type
, selectCreate type backed by DynamoDB table now
and underModel information
, provide a name for the GraphQL Type (Model name) and the specify the fields and corresponding data type for each field. Then, provide a name for the DynamoDB table, primary key and sort key and once completed, clickNext
.
- In Step 4, review the API details and then click on
Create API
. It starts creation of the API and DynamoDB table and once completed, navigate to the API settings page to see a new statusPrivate API On
, indicating the API is private. You will also see a padlock sign attached to Private APIs on the list of AppSync APIs you have created in the region.
Create a VPC with public and private subnet
You can create a VPC using the VPC wizard on the VPC console. You can configure the VPC settings to create a VPC with two public and private subnets, route tables, internet gateway and NAT gateway as shown below. The preview sections shows the resources that will be created. Ensure the option Enable DNS resolution and Enabled DNS host name is selected (refer to the VPC documentation for more details about these two values).
Create an Interface Endpoint for AWS AppSync
- Navigate to the Amazon VPC console and in the left navigation pane, choose
Endpoints
and then selectCreate endpoint.
- You can specify a name tag for the endpoint e.g.
appsync-private-api-endpoint
- For Service category, keep it set to AWS Services.
- For Service Name, set it to
com.amazonaws.{region}.appsync-api
while replacing region with the current region you are working on. - For VPC, select the VPC you created in the previous step.
- Expand the Additional settings section and ensure the checkbox Enable DNS name is selected. This will associate a private hosted zone with the VPC that contains a record set that enables you to leverage Amazon’s private network connectivity to the AppSync service while making requests using the AppSync API url ( e.g.
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
). Note: Enabling Private DNS will prevent resources in the VPC from being able to invoke other AppSync public APIs using the AppSync generated API URL. This is because the request to the public API will be routed via the interface endpoint which is not allowed for public APIs. To invoke public APIs in this scenario, it is recommended to configure custom domain names on public APIs, which can then be used by resources in the VPC to invoke the public API.
- Select the two AZs and one subnet in each AZ to deploy the endpoint. I elected to create the endpoints in the private subnets
- For Security groups, I created a new security group
appsync-private-api-endpoint-sg
which only allows internal VPC traffic on port 443 (HTTPS). You can configure the security group to narrow it down to the subnet IP address range or the IP address of the resource that will invoke the API. - For the VPC endpoint policy, I selected
Full access
to allow any AWS principle to invoke the private API. If you are using Identity and Access Management (IAM) authorization mode for your AppSync API, it is recommended that you scope down the custom policy to grant the necessary permissions only to the required IAM users and roles. - Leave other options as default and select
Create endpoint.
Invoking the Private API from the EC2 instances
We will use an EC2 instance deployed in my private subnet to invoke the API. The security group attached to the EC2 instance and VPC endpoint will need to allow inbound and outbound traffic in both directions. You can use AWS System Manager Session Manager to connect to the EC2 instance and VPC Reachability Analyzer to troubleshoot connectivity issues.
Now to invoke the Private API, you can use two different domain name system (DNS) names:
- Private DNS (if you have enabled private DNS naming while creating the VPC endpoint)
- Interface VPC endpoint public DNS hostnames
The details page of the VPC endpoints shows these two DNS names as shown below.
With Private DNS, the base URL to invoke the API will be in the format
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
which is the same API URL generated by AppSync when the private API was created (refer to the AppSync API settings page on AppSync console). Using private DNS implies you do not need to make any changes to your application if it is already using the AppSync generated API URL.
With the interface VPC endpoint public DNS hostnames, the base URL to invoke the API will be in the format
https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql
or you can also use the AZ specific DNS hostname if you have deployed an endpoint in the AZ,
https://{vpc_endpoint_id}-{endpoint_dns_identifier}-{az_id}.appsync-api.{region}.vpce.amazonaws.com/graphql.
Using the VPC endpoint public host name will require the AppSync API endpoint hostname to be passed as Host or x-appsync-domain header to the request (see example below).
To test out the sample Todo API, we will be using the Private DNS to invoke the API. You can use any command line tool of your choice, here I will use curl to send queries and mutations, and wscat to set up subscription. On Amazon EC2 linux, you will need to install npm which is required to install wscat. Replace all values in the curly bracket with the corresponding values from your AWS account.
Testing Mutation Operation – createTodo
Request
Testing Mutation Operation – createTodo
Response
Testing Query Operation – listTodos
Request
Testing Query Operation – listTodos
Response
Testing Subscription Operation – Subscribing to createTodo
mutation
For details on setting up GraphQL subscriptions on AppSync, see Building a Real-time WebSocket Client. I will use the EC2 instance in the private subnet in AZ1 as the client initiating the subscription request to onCreateTodo
subscription and the EC2 instance in the private subnet in AZ2 as the client invoking the createTodo
mutation.
I will run the command below on the EC2 instance in the Private Subnet in AZ1
On the EC2 instance in the Private Subnet in AZ2, I will execute the createTodo Mutation.
On the EC2 instance in the Private Subnet in AZ1 I can see that the subscription notification is trigged, and the message notification appears as shown below
If you intend to use the VPC endpoint public host name to setup subscription, here is a sample query to initiate the connection on EC2
then a sample query to start the subscription after initializing the connection is as follows:
Important things to know
- APIs can only be set up as private a creation time. An API cannot be made private after it has been created and a Private API cannot be changed after it has been created.
- Setting up VPC interface endpoint for AWS AppSync with Private DNS enabled will prevent resources in the VPC from being able to invoke other AppSync public APIs using the AppSync generated API URL. This is because the request to the public API will be routed via the interface endpoint which is not allowed for public APIs. To invoke public APIs in this scenario, it is recommended to configure custom domain names on public APIs, which can then be used by resources in the VPC to invoke the public API.
- With a VPC interface endpoint for AWS AppSync, you can access any Private API in the same AWS account and region. To further restrict access to a Private API you can consider the following:
- ensure only the required admins can create VPC endpoint interface for AWS AppSync
- use a VPC endpoint custom policy to restrict which APIs can be invoked from resources in the VPC
- for resources in the VPC, it is recommended to use IAM authorization to invoke AppSync APIs; remember to ensure the resources are given scoped down roles to the APIs.
- To test your private API, the testing client or query editor will need to send requests to the API through the VPC interface endpoint for AWS AppSync. You can setup your testing client either in your VPC or on-premises data center with a network route to the interface endpoint.
Get started today!
AppSync Private APIs are generally available in all AWS regions where AWS AppSync is available today. You can refer to AWS Regional Services List to find out the regions where AppSync is available. To learn more about Private APIs, refer to the AppSync documentation.