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

Last updated: 2021-10-11

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

Short description

To use an interface VPC endpoint to access an API Gateway private REST API that's in another AWS account, do the following:

  1. Create an interface endpoint in an Amazon Virtual Private Cloud (Amazon VPC) in one account (account A).
  2. Create an API Gateway private REST API in a second account (account B).
  3. Configure a resource policy for the private REST API that allows the interface endpoint to invoke the API.
  4. Set up a method for the private REST API.
  5. Deploy the private REST API.
  6. Test the setup by calling the private REST API from account A.

Resolution

Create an interface endpoint in an Amazon VPC in one account (account A)

Create a new interface VPC endpoint

From account A, follow the instructions in Create an interface VPC endpoint for API Gateway execute-api.

Important: For Policy, choose Full access. It's a best practice to use a VPC endpoint policy to restrict endpoint access by API ID. It's also a best practice to use the API Gateway resource policy to restrict endpoint access by principal. For more information on the security advice of granting least privilege, see Grant least privilege in the IAM User Guide.

As you create the interface endpoint, consider the following:

Retrieve the interface endpoint's VPC Endpoint ID

After you choose Create endpoint and have created the interface endpoint, the VPC Endpoint ID appears. Copy the VPC Endpoint ID of your new interface endpoint (for example: vpce-1a2b3c456d7e89012). Then, choose Close.

Note: You use this ID when creating and configuring your private REST API.

Retrieve the interface endpoint's public DNS name

After you choose Close, the Endpoints page opens in the Amazon VPC console. On the Details tab of the Endpoints page, in the DNS names column, find and copy the public DNS name for your interface endpoint. For example: vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com.

Create an API Gateway private REST API in a second account (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 your interface endpoint ID. 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 the private REST API that allows the interface endpoint to invoke the 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 the 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. Then, choose Create Method.

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

4.    On the / - ANY - Setup pane, for Integration type, choose Mock.
Note: A mock integration responds to any request that reaches it. This response helps when testing.

5.    Choose Save.

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

Deploy the 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, find the message ("If Private DNS is enabled, use this URL:") that includes your private REST API's invoke URL. Then, copy the URL.
Note: You use the private REST API's invoke URL for testing the setup.

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

Test the setup by calling the private REST 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.
Important: During setup, choose the existing security group that you associated with your interface endpoint.

2.    Connect to the Amazon EC2 instance.

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

3.    From the command line of your Amazon EC2 instance, use any of the following curl commands to call the private REST API in account B.
Note: For more information, see Invoking your private API using endpoint-specific public DNS hostnames. For more information about curl, see the curl project website.

To call your API using a 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.

To call your API using a 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.

To call your API using a public DNS name with a host header

curl -i https://vpce-1a2b3c456d7e89012-f3ghijkl.execute-api.region.vpce.amazonaws.com/stage-name -H "Host: 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 a1bc234d5e.execute-api.region.amazonaws.com with your private API's invoke URL from the API Gateway console.

To call your API using a 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.

4.    Review the command output. API Gateway returns a 200 OK response if the connection is successful.