- Newest
- Most votes
- Most comments
Hi @Joshua,
Maybe I've been not so clear,
But here it goes, with a little bit more detail
Go to AWS Console, Search API gateway and go to Custom domain names on the left
Create a custom domain, In my case I will use dcaballero.net, for example petapi.dcaballero.net. In order to do this properly you need an AWS ACM certificate, with the base domain dcaballero.net and alternative name wildcard *.dcaballero.net in my case!
Now, after the custom domain for api gateway is created you will see a record named "API Gateway domain name" and it will look like:
<some-id>.execute-api.us-east-1.amazonaws.com
Now, in this custom domain go to the tab "API mappings" and map your API gateway and its stage.
Now, in your DNS manager, make sure you have a CNAME dns record for this endpoint. In my case:
[~]$ dig petapi.dcaballero.net CNAME +short
d-tzbua5tzr1.execute-api.us-east-1.amazonaws.com.
After the dns is resolving properly the endpoint of the custom domain, you will be able to call the API like this:
[~]$ curl -v https://petapi.dcaballero.net/pets
* Trying 23.21.127.126:443...
* Connected to petapi.dcaballero.net (23.21.127.126) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
* CApath: none
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=dcaballero.net
* start date: Feb 16 00:00:00 2023 GMT
* expire date: Mar 16 23:59:59 2024 GMT
* subjectAltName: host "petapi.dcaballero.net" matched cert's "*.dcaballero.net"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M01
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* h2h3 [:method: GET]
* h2h3 [:path: /pets]
* h2h3 [:scheme: https]
* h2h3 [:authority: petapi.dcaballero.net]
* h2h3 [user-agent: curl/7.85.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x561b1abb2b00)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /pets HTTP/2
> Host: petapi.dcaballero.net
> user-agent: curl/7.85.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200
< date: Thu, 16 Feb 2023 15:36:59 GMT
< content-type: application/json
< content-length: 184
< x-amzn-requestid: 905fc8fc-f37e-4df8-b11b-d14681cca5a0
< access-control-allow-origin: *
< x-amz-apigw-id: AcEQSF6NoAMFqxQ=
< x-amzn-trace-id: Root=1-63ee4d9b-393461651075686265d1716e
<
[
{
"id": 1,
"type": "dog",
"price": 249.99
},
{
"id": 2,
"type": "cat",
"price": 124.99
},
{
"id": 3,
"type": "fish",
"price": 0.99
}
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host petapi.dcaballero.net left intact
Hope this is better for your use case.
Hi @Joshua,
You can create a private hosted zone in r53, with an internal domain and a record for the API Gateway.
For example,
Hosted Zone A (internal) - domain apex: internal.mydomain.com
The VPC will resolve the records on that hosted zone first, make sure there is a record for your API gateway:
CNAME - api.internal.mydomain.com -> https://{rest-api-id}-{vpce-id}.execute-api.{region}.amazonaws.com/{stage}
Now, VPC Endpoint must exist anyways.
In your deployment or re-build process you can update that record everytime you deploy and the services if running inside the same VPC will resolve the API gateway using api.internal.mydomain.com regardless its CNAME value at the hosted zone.
Hope that helps!
Hi @Joshua,
in your case, like I said before you can use one single CNAME record, the record can be updated everytime you deploy its new API gateway so it will always point to whatever is the API Gateway endpoint. Now, that doesn't need any special Host header or similar, and you can also use API Gateway custom domains to avoid the usage of API Gateway endopoints.
How to custom domains: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html
Now, if your use case is a bit more complex, like a ReviewApps scenario where each deployment is generating a new API gateway per MR or PR, then you will need a different strategy in your record, either composing version or short sha over the custom domain record.
Hope that helps! cheers!
Hi David, this is sadly a non-answer as this is what I stated that I tried and it didn't work. I understand this solution, it's what I came up with, but it required passing the host header to work. Please see my linked Stack Overflow question for more details and read the whole question before responding, thanks for the help.
Relevant content
- asked 2 years ago
- Accepted Answerasked 4 years ago
- AWS OFFICIALUpdated 2 years ago
- How do I use an interface VPC endpoint to access an API Gateway private REST API in another account?AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 3 years ago
Hi @DavidCabllero, thanks for the reply.
As I stated in the question I already implemented that and it doesn't work for my use case because it becomes necessary to pass in a Host header like "{rest-api-id}.execute-api.{region}.amazonaws.com" when calling the url of the CNAME/Alias record from the public/private hosted zone.
I need the endpoint set up such that it doesn't require special headers to call, as I already stated. Does this make sense?