44

I am creating an api using API Gateway and Lambda. Using the url designated in the API Gateway Stage editor everything works fine; however, when I try and move to a custom domain I am running into some issues.

The first thing I tried was using a CNAME record in Route 53 straight from my domain onto the domain that I got from the API Gateway. That was returning some errors and I think it is the incorrect solution is that correct?

Next I tried the Custom Domain Names feature in API Gateway. My understanding is this will roll up a CloudFront distribution that I can then map onto from Route 53. When I created the custom domain and added a Domain Mapping it provides me with a url to what I assume is a CloudFront distribution. The link is returning a 403 response and no distribution has been made in CloudFront. What is a good way of debugging this problem?

BBS
  • 1,351
  • 2
  • 12
  • 27
  • 3
    You always have a CloudFront distribution when you are using API Gateway, not just when you enable custom URLs. You won't see it in your CloudFront dashboard because it is managed behind the scenes and you don't have direct access to it. – Mark B Apr 07 '16 at 12:59
  • 1
    Okay that makes sense. That and the fact that I wasn't waiting long enough for CloudFront to roll up were the problems. I came in this morning and it was working. – BBS Apr 07 '16 at 22:01
  • 1
    I had this issue and found that waiting till the next morning "resolved" it. I think that the process of creating and assigning the edge domain is very asynchronous. – Rich May 21 '19 at 20:46
  • Bty my I am getting {“message”:“Forbidden”} on my hosted domain name URL but when I open api endpoint my service is accessed. Note my api is open but my route 53 entry is in different aws account and my custom domain created for api and cloudfront are in different aws account – Ashish Karpe Feb 07 '22 at 17:53

6 Answers6

33

tldr; Make sure you're not still adding /path/ANDSTAGE but just /path because APIGW will map this for you.

Here is the developer guide if you haven't seen it. http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html

All you need to do is set up a CNAME with your DNS provider pointing at the CF distribution that API Gateway gives you. You won't be able to make API calls directly to the CF distribution. API Gateway maps the API/stage from the Base Path mapping you set up in API Gateway so only API calls directed at the domain name will work correctly.

diegoaguilar
  • 8,179
  • 14
  • 80
  • 129
jackko
  • 6,998
  • 26
  • 38
  • I wonder if it's possible to use an APIGW custom domain without a cloudfront distribution... – Marcello Romani Jan 07 '22 at 23:59
  • Ah, it depends on the endpoint type, Edge or Regional... – Marcello Romani Jan 08 '22 at 00:00
  • 1
    Bty my I am getting {“message”:“Forbidden”} on my hosted domain name URL but when I open api endpoint my service is accessed. Note my api is open but my route 53 entry is in different aws account and my custom domain created for api and cloudfront are in different aws account – Ashish Karpe Feb 07 '22 at 17:56
30

You need to use host header in your request. Host should be your custom domain.

curl https://<cf-id>.cloudfront.net/myapi -H "Host: api.myapi.com"
Santosh Sahu
  • 333
  • 3
  • 2
  • adding the Host header was the missing piece for me. I have an API key required for the APIG, and was already providing the x-api-key custom header, but without the Host header, the request was always forbidden when using cloudfront – Thiago Silva Nov 17 '17 at 22:59
  • 2
    This is the real answer! – Nate Barbettini Dec 20 '17 at 15:54
  • 26
    No, it's not. The whole point of using a custom domain is so that you can use *it* instead of using `cloudfront.net`. – JamesQMurphy Jun 17 '18 at 04:29
  • 1
    It's useful to verify everything is working before connecting it to the 'real' domain. – shrumm Dec 31 '18 at 00:27
  • I tried with postman and this solved half of the problem. But you can't set Host header in AJAX requests, the browser does not let you. Is there a solution to this? – Steven Sep 04 '20 at 23:05
  • In my case, adding this Host header with my desired api.example.com is what allowed my api.example.com Route 53 record to go through - I didn't touch my cloudfront console tab. – Fernando Piancastelli Apr 16 '21 at 18:51
21

In my case I had to add base path mapping.

Derrick Petzold
  • 1,118
  • 13
  • 13
  • 2
    Yes, even if you don't want to have an extra bit in your url layout (e.g. api.mydomain.com/whatever), you will need to add a `/` base path mapping in order to make it work – bormansquirrel Feb 19 '19 at 12:06
  • This answer solved my problem. – Jesse Barnum Jan 01 '22 at 00:10
  • The resource is called 'aws_api_gateway_base_path_mapping' - easy to miss in the documentation since the example in 'aws_api_gateway_domain_name' doesn't explicitly include it. – Joseph Siefers Nov 11 '22 at 19:03
5

In my case the problem was that I didn't create an API mapping in the custom domain name configuration for api-gateway.

Api gateway main menu -> custom domain names -> select your newly created custom domain name in the list -> click api mappings on the right -> create mapping between your deployed api and the custom domain name.

OpsYogi
  • 51
  • 1
  • 2
1

In my case Legacy cache settings headers was the issue.

If you have selected Legacy cache settings in cloud-front behaviour In cloud-front distribution under behaviour-> Legacy cache settings-> Header drop down

After selecting value as None solved my problem

arpanexe
  • 52
  • 6
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30683114) – l33tHax0r Dec 27 '21 at 17:01
0

I'll post another answer here, as our case was a bit more complex, and this may save quite a few hours to someone in the future (I do include myself in this "someone").

We're using Global Accelerator to be able to provide a static IP for some of our APIs. The trick here was that one of these APIs was still using an EDGE endpoint instead of a PRIVATE endpoint. This was causing the same {"message":"Forbidden"} issue, with the right domain mapping and without having anything in API Gateway Execution logs.

zessx
  • 68,042
  • 28
  • 135
  • 158