I tried to create a HTTP API through API Gateway.
This API generated a URL e.g. https://{api-id}.execute-api.{region}.amazonaws.com/
This endpoint works as intended.
After this; I created a custom domain name and under "Api Mappings", I added this newly created API, set the stage the $default and left Path (Optional) as blank. This generated another endpoint (which is supposed to be added as an A record in Route53). When I try to hit this new endpoint; I get {"message":"Not Found"}. This "connection" between the custom domain endpoint and the working api gateway endpoint doesn't seem to work. Any pointers on how to fix this?
Other Information:
I own the custom domain
Adding a custom domain required uploading a SSL certificate (I had a valid one and I uploaded it - verified and all good)
The API is a basic HTTP API which refers to a Cloudfront URL. This endpoint is fully functional and working as expected.
Endpoint Type: Regional
No multiple "Stages" for API/Routes - only a $default one
Related
I have a REST API serving behind API Gateway.
I have a Route53-hosted zone: myAWSHostedDomain.myCompanyDomain.com
I have also created a certificate in ACM: myApp.myAWSHostedDomain.myCompanyDomain.com
The certificate has an additional domain:
myApp.myCompanyDomain.com
The cert has been issued without any problem, both domains were validated.
In the company non-AWS-hosted zone myCompanyDomain.com, I have a CNAME pointing myApp to myApp.myAWSHostedDomain.myCompanyDomain.com. It resolves OK.
I have configured a Custom Domain for that API Gateway using that certificate. The name that shows is myApp.myAWSHostedDomain.myCompanyDomain.com. Which is fine because it's the main domain for that cert.
The problem I have is that all the requests made to myApp.myCompanyDomain.com fail with a 403 Forbidden error, while those same requests on the myApp.myAWSHostedDomain.myCompanyDomain.com work just fine. The app code has nothing to do with it, a request for a favicon.ico behaves the same way.
The API Gateway endpoint is configured as a Regional one.
Could it be that API Gateway's custom domain only takes the main domain from the certificate and doesn't work with the additional ones? Is there a way to fix this?
So, the problem is that the request fails with a 403 forbidden error, because API Gateway is unable to set the correct Host header, which is required for the request to succeed.
If I do:
curl https://myApp.myCompanyDomain.com/favicon.ico -H "Host:myApp.myAWSHostedDomain.myCompanyDomain.com"
Then, it works.
Hence, the options here are the following:
Create a DNS record in Route53 for myApp.myCompanyDomain.com.
While calling the API, add a Host header to the request, with the value set as the value for the DNS record.
Create a new API Gateway where the main custom domain corresponds with the one in the API Gateway: myApp.myCompanyDomain.com work instead of myApp.myAWSHostedDomain.myCompanyDomain.com work.
I've been wasting about 12 hours going in circles in what seems like this:
I am trying to just make a simple static landing page in lambda and hook the root of a domain to it.
The landing page works, but api gateway didn't because AWS doesn't seem to set permissions properly by default ("internal server error" with API gateway and lambda on AWS) but now the gateway link works.
So the next steps were the following:
add a custom domain name in the api gateway
add the api mapping in the custom domain name
in route 53, create a wildcard certificate with *.domain.com and domain.com
create an A record that points to the api gateway with domain.com
create a CNAME record that points to the A record
and I get an error 403 with absolutely nothing in the log. I log both 'default' and '$default' stages in the api gateway.
I read https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/ which is all about looking at what's in the logs...
and I find the doc is both everywhere and nowhere because it's built as chunks of 'do this' and 'do that' without ever painting a whole picture of how each piece is connected to the other, or any graph with the hierarchy of services, etc. Reminds me of code that works only when you follow the example documented and breaks otherwise.
I'm sure I'm doing something wrong, but given the lack of logs and lack of cohesive documentation, I have no idea about the problem.
Not to mention that http doesn't even connect, just https.
Can anyone outline the steps needed to achieve this? essentially: [http|https]://(www).domain.com -> one lambda function
You cannot use API Gateway for an HTTP request; it only supports HTTPS.
From the Amazon API Gateway FAQs (emphasis mine):
Q: Can I create HTTPS endpoints?
Yes, all of the APIs created with Amazon API Gateway expose HTTPS endpoints only. Amazon API Gateway does not support unencrypted (HTTP) endpoints. By default, Amazon API Gateway assigns an internal domain to the API that automatically uses the Amazon API Gateway certificate. When configuring your APIs to run under a custom domain name, you can provide your own certificate for the domain.
You can use CloudFront to automatically redirect HTTP to HTTPS. How do I set up API Gateway with my own CloudFront distribution? provides a pretty simple walkthrough of connecting an API Gateway to CloudFront (you can skip the API Gateway portion and use the one you created). The important thing you'll need to do that is not in that document is to select Redirect HTTP to HTTPS.
If you truly need HTTP traffic you're probably going to need to go with an ALB.
I have created a sample API Gateway using "HTTP API".
I then add a custom domain and added the relevant CNAME record to the DNS.
I then go on Configure API mappings, to add the HTTP API but I get the following error message:
Mixing of REST APIs and HTTP APIs on the same domain name can only be accomplished through API Gateway's V2 DomainName interface. Currently, WebSocket APIs can only be attached to a domain name with other WebSocket APIs. This must also occur through API Gateway's V2 DomainName interface.
Note that adding normal "REST API" works fine.
What is the problem exactly and how do I fix it?
Note that I have since deleted all custom domains, and added this domain fresh, and it still does not work..
I got a second error message and this may explain the reason:
The error message says: "These API types may only be associated to REGIONAL domain names": this means that an HTTP API can only be associated with a REGIONAL custom domain so EDGE is not (hopefully yet) supported with EDGE custom domains.
You only have the option to use a REST API, in order to associate it with an EDGE custom domain, or to create multiple HTTP API deployments in multiple AWS Regions and use Route53 (or you own DNS provider) to map each regional deployment endpoint based on a low-latency strategy.
I'm trying to set up an API using a REGIONAL custom domain that routes HTTP requests to ALB.
The domain is registered with another DNS provider so I will not be using Route53.
Concept:
/path/to/service --> ALB (Listener: /path/*) --> ECS
I first tried with the original invoke URL https://cuxxxxmvk0.execute-api.ap-east-1.amazonaws.com/stage/path/to/service, it returns ALB context path error (It's expected because ALB gets /stage/path/to/service which doesn't hit any prefix).
Then I created a custom domain with API mapping (no base path) that maps to the stage, and try invoking it with the provided "API Gateway domain name" (The one generated by custom domain). Full URL: https://d-yjexxxds3.execute-api.ap-east-1.amazonaws.com/path/to/service
However, it returns {"message":"Not Found"}
API Gateway domain name
So my question here is:
How does the "API Gateway domain name" generated by custom domain works? Can I directly invoke the API with it?
Is it a must to CNAME it (i.e. CAME api.mydomain.com d-yjexxxds3.execute-api.ap-east-1.amazonaws.com)?
Can I make my final endpoint to be api.mydomain.com/path/to/service without the stage in path?
From the question I can see that you're trying to use CNAME to resolve to URL/some/path but that's not how it works. DNS service will only map your CNAME to some other URL only. The path (/some/path) part will remain same from your domain or API-GW URL.
Other thing to note here is that since you're not using Route53, you do not need Custom Domain Name of API-GW. Create a CNAME which is something like
example.com CNAME d-yjexxxds3.execute-api.ap-east-1.amazonaws.com
I would suggest you add /stage in your ALB prefix so that it can be accessed by API-GW and your own domain.
How does the "API Gateway domain name" generated by custom domain works? Can I directly invoke the API with it?
Yes, you can
Is it a must to CNAME it (i.e. CAME api.mydomain.com d-yjexxxds3.execute-api.ap-east-1.amazonaws.com)?
It is either CNAME (when the DNS is managed by an external provider) or it can be ALIAS (directly returning A records if you manage the DNS in Route53). Please note you need a validated certificate in the certificate manager.
Can I make my final endpoint to be api.mydomain.com/path/to/service without the stage in path?
https://d-xxxxxxds3.execute-api...
As far I know you should invoke the API by defined custom domain name (api.mydomain.com). If calling the d-.. domain will work, I'm not sure
https://api.mydomain.com/path/to/api
I'm not sure what is not working in your setup. Indeed in the custom domain mapping you can have a mapping directly to certain stage, so you may invoke the API as https://customdomain/path/to/api We have it working this way.
Long story short, your setup / idea is generally good. You may enable logging on the API Gateway or stage to find out what is not working (if the NOT FOUND is retuned by the API GW or backend ELB)
I'm currently testing out how to setup CloudFront with Regional Api Gateway that includes a Custom Domain but have run into a bit of snag.
I would like to be able to use: https://mySuperDomain.com/rest/get_stuff
Setup:
Api Gateway
I have a regional Api Gateway that points to a Lambda function.
The Gateway includes a Cognito Authorizer
The Integration Request is a Lambda Proxy
The base Resource is "/" with Methods: GET & OPTIONS
The stage is "dev"
Custom Domain name and ACM are set to "mySuperDomain.com"
Configuration is also Regional
Directly calling the url works as expected: https://XXXXXXXX.execute-api.REGION.amazonaws.com/dev
Route53
A record is an alias that points to the CloudFront Distribution
Base domain also contains NS, SOA, and MX
CloudFront
Origins:
Alternate Domain Names: www.mySuperDomain.com & mySuperDomain.com
Origin and Domain Path: XXXXXXXX.execute-api.REGION.amazonaws.com/dev
HTTPS only
Behaviors:
/rest/*
Origin group is set to the Origin
HTTPS only
This is where things get confusing.
When including no headers, I get a "Missing Authentication Token" error. This signals to me that I'm hitting the correct endpoint but the Authentication Token is not making it through CloudFront.
However, when I whitelist what I describe as the kitchen sink: "Authorization, Host, Origin, Referer, Accept-Datetime", I get 403 Forbidden when calling: https://mySuperDomain.com/rest/get_stuff.
What am I missing in order to access the specified custom domain URL? Thanks ahead of time.