How do I set up API Gateway with my own CloudFront distribution?

8 minute read
1

I want an edge-optimized API endpoint in Amazon API Gateway, but I want to create my own Amazon CloudFront distribution for it.

Short description

If your API clients are geographically dispersed, then use an edge-optimized API endpoint in API Gateway. This type of endpoint acts as a Regional endpoint with an AWS managed CloudFront web distribution to improve client connection time.

To use the global CloudFront content delivery network and maintain more control over the distribution, use a Regional API with a custom CloudFront web distribution.

Resolution

Prerequisites: Create an AWS Lambda function to integrate with your API Gateway REST API, and create a Regional API in API Gateway.

Create an SSL/TLS certificate in AWS Certificate Manager (ACM) in the us-east-1 Region and in the same AWS Region as your API Gateway REST API. To get a certificate for a domain name that's issued by or imported into ACM, complete the following steps:

  1. Register your internet domain. You can use either Amazon Route 53 or a third-party accredited domain registrar.
  2. Create an SSL/TLS certificate for the domain name in ACM, or import one into ACM.

Set up a GET method for your API

Complete the following steps:

  1. Open the API Gateway console.
  2. Choose the name of your new Regional API.
  3. Choose Create resource.
  4. For Resource name, enter greetings.
  5. Choose Create method.
  6. Choose GET for Method type, and select Lambda Function for Integration type. Then, toggle the Lambda proxy integration button and select your Lambda function.

Deploy your API and identify your API invoke URL

Complete the following steps:

  1. Deploy your API to a stage.
  2. At the head of the Stage Editor pane, copy the Invoke URL for the GET HTTP method of the greetings resource to your clipboard.

API Gateway API Invoke URL example:

https://restApiId.execute-api.region.amazonaws.com/stageName/greetings

Test your API for a 200 OK response

To confirm that your API returns a 200 OK response, test your API invoke URL through the API Gateway console, the Postman app, or curl. For more information about Postman and curl, see the Postman website and the curl website.

Use curl to test your API for a 200 OK response

Based on your operating system, run one of the following commands.

Note: Replace https://restApiId.execute-api.region.amazonaws.com/stageNamee/greetings with your API invoke URL.

For Linux, run the following command:

curl -IX GET https://restApiId.execute-api.region.amazonaws.com/stageName/greetings

For Windows PowerShell, run the following command:

curl https://restApiId.execute-api.region.amazonaws.com/stageName/greetings

Note: If you get a status code other than 200 OK, then check the console to confirm that your API is deployed to your stage. Also, confirm that your invoke URL correctly specifies your stage.

Create a CloudFront web distribution

Complete the following steps:

  1. Open the CloudFront console.

  2. Choose Create Distribution.

  3. For Origin Domain Name, enter your API invoke URL. Then, delete the stage and resource name.
    Origin domain name example:

    https://restApiId.execute-api.region.amazonaws.com
  4. For Protocol, select HTTPS Only.
    Note: API Gateway doesn't support unencrypted (HTTP) endpoints. For more information, see Amazon API Gateway FAQs.

  5. For Minimum Origin SSL Protocol, it's a best practice to choose TLSv1.2. Don't choose SSLv3. API Gateway doesn't support the SSLv3 protocol.

  6. For Origin Path, enter your API stage name with a slash in front of it (/stageName). Or, to enter the stage name yourself when you invoke the URL, don't enter anything in Origin Path.
    Note: If you enter an incorrect stage name for Origin Path and then you invoke the CloudFront distribution, then you might get an error. For example, you might get an unauthorized request error that returns the message "Missing Authentication Token" and a 403 Forbidden response code.

  7. (Optional) To forward custom headers to your origin, enter one or more custom headers for Origin Custom Headers.

  8. Follow the instructions in the If you're using IAM authentication for your API or custom domain names for your CloudFront web distribution section, if applicable.

  9. (Optional) Under Distribution Settings, configure the additional settings that you want to customize.

  10. Choose Create Distribution.

  11. Wait 15-20 minutes for your distribution to deploy. When the distribution Status appears as Deployed in the console, the distribution is ready.

For more information, see Create a distribution.

Test your CloudFront web distribution

Complete the following steps:

  1. Open the CloudFront console.

  2. Copy the Distribution domain name of your distribution to your clipboard.
    Non-custom domain name example:

    a222222bcdefg5.cloudfront.net
  3. Test the domain name for a 200 OK response. If you get a 500 server error code, then the distribution might not be deployed. If you get no response, then the CloudFront DNS record hasn't propagated yet. In either case, wait 15-20 minutes after you create your distribution, and then retry the procedure.

Important: The preceding steps are for API resources that don't have AWS Identity and Access Management (IAM) authentication turned on for any of the resource methods. If you have methods with IAM authentication, then append the resource name to the end of the distribution domain name when you invoke your API. The full invoke URL (including the resource name) looks similar to one of the following examples.

API Gateway API invoke URL with an origin path example:

https://distributionDomainName/stageName/resourceName

API Gateway API invoke URL without an origin path example:

https://distributionDomainName/resourceName

For more information on how to test your distribution, see How do I activate IAM authentication for API Gateway APIs?

If you're using IAM authentication for your API or custom domain names for your CloudFront web distribution

By default, CloudFront doesn't forward incoming Authorization headers to the origin (for this use case, API Gateway). If you're using IAM authentication for your API or custom domain names for your distribution, take one of the following actions.

(For IAM authentication) Add the Authorization header to your CloudFront allowlist

Complete the following steps:

  1. Create a CloudFront distribution.
  2. On the Create Distribution page, for Default cache behavior and Cache key and origin requests select Legacy cache settings.
  3. Choose Include the following headers on the Headers dropdown list. Then, select Authorization from the list of headers that appear. Configure the headers that you want to be forwarded to your API.
    -or-
    For Cache key and origin requests, under Cache Policy, choose either an existing cache policy or create a new cache policy. The policy must add the Authorization header to your CloudFront allowlist.
  4. (Optional) To test the setup, do the following:
    Create the required Signature Version 4 signature for your API Gateway endpoint programmatically. For the host value, enter your API Gateway invoke URL. For the endpoint value, enter your CloudFront web distribution URL.
    API Gateway invoke URL example:
    example_api_id.execute.example_region.amazon.com
    CloudFront web distribution URL example:
    d######.cloudfront.net

Note: If you're using the Postman app, then in the Authorization tab, for Type, choose AWS Signature. Then, enter the Access Key and Secret Key. Postman uses the credentials that you enter to generate the required headers. Then, use the Authorization header (and all SignedHeaders) generated from the Signature Version 4 process to send the API request to the CloudFront distribution.

(For custom domain names or IAM authentication) Set up a Regional Custom domain name in API Gateway to access your API

Complete the following steps:

  1. Create a new Regional API in API Gateway or change your edge-optimized API Gateway API to a Regional API.

  2. Set up a Regional custom domain name for the API and create an API mapping for your API.
    Note: Use this custom domain name when you access your API through CloudFront.

  3. Create a CloudFront web distribution, but for Origin Domain Name, enter your API Gateway target domain name instead of your API invoke URL.
    Note: Find your API Gateway target domain name in the Endpoint configuration section of your custom domain details.
    API Gateway target domain name example:

    d-######.execute-api.example-region.amazonaws.com
  4. On the Create Distribution page, for Default cache behavior and Cache key and origin requests, select Legacy cache settings.

  5. Choose Include the following headers on the Headers dropdown list. Then, select the Host and Authorization from the list of headers that appear. Configure the headers that you want to be forwarded to your API.
    -or-
    For Cache key and origin requests, under Cache Policy, choose either an existing cache policy or create a new cache policy. The policy must add the Authorization header to your CloudFront allowlist.

  6. Under Distribution Settings, for Alternate domain name, enter the custom domain name that you created.

  7. For SSL Certificate, select Custom SSL Certificate. Then, add the AWS Certificate Manager (ACM) certificate for that domain.

  8. After you deploy the CloudFront web distribution, configure the DNS Record to map the custom domain to the CloudFront web distribution. To do this, create either an alias or CNAME record. For more information, see Use custom URLs by adding alternate domain names (CNAMEs).

  9. (Optional) To test the setup, create a Signature Version 4 signed request for your custom domain name programmatically.
    Note: You can also use the Postman app to test the setup.

3 Comments

I've followed the solution described in the article, particularly the part related to IAM Authenticated REST API Gateways behind a Cloudfront Distribution with a Custom Domain Name but I'm recieving the following error :

Error: 421 Client Error: Misdirected Request for url: https://custom-api.petereskandar.eu/dev/api

Where custom-api.petereskandar.eu is the alternate domain name used for the Cloudfront Distribution and also acts as a Custom Domain Name for the REST API.

any idea on how to get this working ?

profile picture
replied a year ago

After hours of work and multiple testing attempts, we managed to make it work by following the steps below :

  • Create a IAM Authenticated Regional API Gateway.
  • Create a custom domain name for that API Gateway, let's say api.customdomain.eu.
  • Don't create a record on DNS/Route53 for that API Gateway Custom domain name as you will need it for the CloudFront Distribution.
  • Create a CloudFront Distribution with an alternate Domain Name, the same as the custom domain name associated with the API Gateway.
  • Add the API Gateway as an Origin to the CloudFront Distribution.
  • Disable caching on CloudFront or create a new Cache Policy that forwards Authorization headers to the Origin
  • Create a CNAME/Alias Record that maps the custom domain name "api.customdomain.eu" to the CloudFront Distribution domain name.
  • Start testing using a Python script that signs "sigv4" your requests to the CloudFront Distribution or use Postman with AWS Signature Authorization enabled. The host used should be the custom domain name "api.customdomain.eu".
profile picture
replied a year ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
EXPERT
replied a year ago