I've created an expressjs api and hosted in AWS lambda with an api gateway for the same. It is working fine as expected with the url:
https://[api-id].execute-api.[region].amazonaws.com/prod/api/v1/todos
But I want to invoke it using a custom domain and I confgiured it using the custom domain option of the api gateway. I've registered my domain using google domains and I've added the CNAME entry in DNS configuration to map it to the cloudfront target domain name. So far so good.
The api gateway custom domain configuration is as follows with corresponding mappings.
My problem is that I'm getting the message Cannot GET /aprod/api/v1/todos
, on invoking with url:
and forbidden
on
.
My cloudwatch logs is as follows. If I'm not invoking with custom domain it works fine (green block), else no specific message (red block).
I've already spent two weekends on this issue, any help is much appreciated.
Based on my experience, there are two possible causes.
If your origin server is inside private VPC, it is necessary to create VPC Link and Network Load Balancer (NLB) instead of Application Load Balancer (ALB).
See more detail: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html
CNAME should point to the API Gateway endpoint instead of CloudFront. In this case, the value of CNAME should be like this.
https://[api-id].execute-api.[region].amazonaws.com
Otherwise, the access through the custom domain is passed directly to the CloudFront.
In my case, A record is used to point to the alias of NLB. It is a functionality of Route53 but using A record might be necessary instead of CNAME.