How can I access an API Gateway private REST API in another AWS account using an interface VPC endpoint?

Last updated: 2020-05-08

I want to use an interface VPC endpoint to access an Amazon API Gateway private REST API that's in another AWS account. How can I do that?

Short description

Create an interface endpoint in an Amazon Virtual Private Cloud (Amazon VPC) in one account ("account A"). In another account ("account B"), create an API Gateway private REST API with a resource policy that allows calls from the interface endpoint to invoke the API.

Resolution

Create an interface endpoint in account A

1.    In account A, open the Endpoints page of the Amazon VPC console.

2.    Choose Create Endpoint.

3.    On the Create Endpoint page, do the following:
For Service category, choose AWS services.
For VPC, choose the Amazon VPC where you want create the interface endpoint.
For Subnets, select the subnets in which you want to create the endpoint network interfaces. Select multiple subnets in different Availability Zones to make sure that your interface endpoint is resilient to possible Availability Zone failures.
For Enable DNS name, keep the Enable for this endpoint check box selected to enable private DNS for the interface endpoint. With private DNS enabled, you can connect to your private API using private or public DNS.
Note: When you enable private DNS for an interface VPC endpoint, you can no longer access API Gateway public APIs from your Amazon VPC. For more information, see Why do I get an HTTP 403 Forbidden error when connecting to my API Gateway APIs from a VPC?
For Security group, select at least one security group to associate with the endpoint network interfaces. The security group that you choose must have a rule that allows TCP Port 443 inbound HTTPS traffic from either an IP address range in your Amazon VPC or another security group in your Amazon VPC. If you don't have a security group that meets those requirements, choose Create a new security group to create a security group. If you don't specify a security group, a default security group is associated with the endpoint network interfaces.
For Policy, choose Full Access.
Choose Create endpoint.
For Service Name, choose the API Gateway service endpoint. It looks like com.amazonaws.region.execute-api, with region replaced with your current AWS Region. For example, com.amazonaws.us-east-1.execute-api.

4.    Copy the VPC Endpoint ID of your new interface endpoint. It looks like vpce-1a2b3c456d7e89012. You need this ID when creating and configuring your private API.

5.    Choose Close.

6.    On the Endpoints page of the Amazon VPC console, on the Details tab, note the DNS names. Copy the public DNS name for your interface endpoint. It looks like vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com.

For more information, see Create an interface VPC endpoint for API Gateway execute-api.

Create a private REST API in account B

1.    In account B, open the API Gateway console.

2.    Choose Create API.

3.    Under REST API Private, choose Build.

4.    On the Create page, leave Choose the protocol set to REST.

5.    For Create new API, choose New API.

6.    Under Settings, do the following:
For API name, enter a name for your API.
(Optional) For Description, enter a description for your API.
Leave Endpoint Type set to Private.
For VPC Endpoint IDs, paste the interface endpoint ID that you copied, and then choose Add.
Note: When you associate your interface endpoint with your private REST API, API Gateway generates a new Amazon Route 53 alias record. You can use the Route 53 alias to access your private API.

7.    Choose Create API.

For more information, see Creating a private API in Amazon API Gateway.

Configure a resource policy for your private REST API

1.    In the left navigation pane of the API Gateway console, under your API, choose Resource Policy.

2.    On the Resource Policy page, paste the following example resource policy into the text box:

Note: Replace vpce-1a2b3c456d7e89012 with the interface endpoint ID that you copied.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*/*/*",
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": "vpce-1a2b3c456d7e89012"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*/*/*"
        }
    ]
}

For more information, see Set up a resource policy for a private API.

Set up a method for your private REST API

1.    In the left navigation pane of the API Gateway console, under your API, choose Resources.

2.    On the Resources pane, choose Actions, and then choose Create Method.

3.    In the dropdown list under the / resource node, choose ANY, and then choose the check mark icon.

4.    On the / - ANY - Setup pane, for Integration type, choose Mock. A mock integration responds to any request that reaches it, which helps with testing later.

5.    Choose Save.

For more information, see Set up REST API methods in API Gateway.

Deploy your private REST API

1.    On the Resources pane of the API Gateway console, choose Actions, and then choose Deploy API.

2.    In the Deploy API dialog box, do the following:
For Deployment stage, choose [New Stage].
For Stage name, enter a name. For example, dev or test.
Choose Deploy.

3.    On the Stage Editor pane, note the message ("If Private DNS is enabled, use this URL:") with your private API's invoke URL. Copy the URL for testing.

For more information, see Deploy a private API using the API Gateway console.

Test your private API from account A

1.    In account A, launch an Amazon Elastic Compute Cloud (Amazon EC2) instance in the same Amazon VPC as your interface endpoint. During setup, choose the existing security group that you associated with your interface endpoint.

2.    Connect to the EC2 instance.

Note: An EC2 instance can incur charges on your AWS account. If you create an instance for testing this setup only, be sure to terminate the instance when you're done to prevent recurring charges.

3.    From the command line of your EC2 instance, use any of the following curl commands to call the private API in account B. For more information about curl, see the cURL project website.

Private DNS name:

curl -i https://a1bc234d5e.execute-api.region.amazonaws.com/stage-name

Note: Replace https://a1bc234d5e.execute-api.region.amazonaws.com/stage-name with your private API's invoke URL that you copied from the API Gateway console. This command works only if you enabled private DNS for your interface endpoint. For more information, see Invoking your private API using private DNS names.

Route 53 alias:

curl -i https://a1bc234d5e-vpce-1a2b3c456d7e89012.execute-api.region.amazonaws.com/stage-name

Note: Replace a1bc234d5e with your API's ID.
Replace vpce-1a2b3c456d7e89012 with the interface endpoint ID.
Replace region with your API's Region. (For example, us-east-1.)
Replace stage-name with the name of the stage where you deployed your private API. For more information, see Accessing your private API using a Route 53 alias.

Public DNS name with a Host header:

curl -i https://vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com/stage-name -H "Host: https://a1bc234d5e.execute-api.region.amazonaws.com"

Note: Replace vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com with the public DNS name that you noted in the Amazon VPC console.
Replace stage-name with the name of the stage where you deployed your private API.
Replace https://a1bc234d5e.execute-api.region.amazonaws.com with your private API's invoke URL from the API Gateway console.

Public DNS name with the x-apigw-api-id header:

curl -i https://vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com/stage-name -H "x-apigw-api-id:a1bc234d5e"

Note: Replace vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com with the public DNS name that you noted in the Amazon VPC console.
Replace stage-name with the name of the stage where you deployed your private API.
Replace a1bc234d5e with your API's ID.

For more information, see Invoking your private API using endpoint-specific public DNS hostnames.

4.    Review the command output. If the connection is successful, you receive a 200 OK response from API Gateway.