47
votes

I'm trying to set a CNAME on Cloudflare to point to an Amazon API Gateway endpoint. The CNAME is for use when referring to one of my subdomains. The gateway in turn points to the IP of a server on DigitalOcean. I am very new to Amazon web services and would appreciate if someone could give me an overview of the correct configuration for the DNS, Amazon Gateway and Cloudfront (which I think is needed to expose the gateway to DNS servers external to Amazon). Any help would be much appreciated.

UPDATE

I've been going at this for a while now and not making much progress. Does anyone have an idea if this is a viable approach or how else it might be done?

UPDATE2

I thought I needed to add the CNAME record to cloudFlare and just ended up in a redirect loop, observed by:

curl -L -i -v https://sub.mydomain.com/
4
Did you read and follow the steps for using a custom domain name with API gateway at docs.aws.amazon.com/apigateway/latest/developerguide/…?Michael - sqlbot
As far as I can tell that would require me to set up certificates on Amazon. My DNS is setup on cloudflare and so was hoping to keep it simple as it does the ssl for me. The cloudflare domain works when calling it directly, so it seems to be just the call from cloudflare to the cloudfront that's the issue.Silian Rails
"My DNS is setup on Cloudflare" and "Cloudflare does SSL for me" are completely unrelated things. For Cloudflare to do SSL it must not only do your DNS but also actually proxy requests for you. You seem to be mixing up different concepts in this question, leaving it very unclear what you are asking. Please try to explain what you are trying to accomplish, rather than how you are trying to accomplish it -- using a custom hostname and a Cloudflare-provided SSL certificate in front of an API Gateway endpoint is what it sounds like you're trying to do.Michael - sqlbot
Sorry about the confusion. I'm not a networking person and I guess it shows! I've got Cloudfront set up so that when I query my API through the cloudfront domain it works. My DNS is set up on Cloudflare and conversion of http to https through a page rule. I'm trying to add a sub domain api.mydomain.com to Cloudflare with a CNAME record to the cloudfront domain but it doesn't work.Silian Rails
Okay, but that's not going to get you any Cloudflare SSL. Can you mention the hostname in question? There's no obvious reason for a redirect loop, but then again there's also no obvious reason why you need CloudFront in the chain in order to do what you're trying to do... at least, not based on the available information, unless you're trying to use an SSL certificate from Amazon Certificate Manager, which is integrated with CloudFront (but has not been otherwise mentioned so far).Michael - sqlbot

4 Answers

50
votes

NOTE: It seems this method doesn't work anymore as AWS now only accepts certificates from certain authorities. I haven't tested it myself, but the answer by Gunar looks promising.

There are several reasons why it doens't work to simply point Cloudflare at your API Gateway domain and call it a day:

  • API Gateway uses shared hosting so it uses the domain name to figure out what API to send requests to. It has no way of knowing that api.yourdomain.com belongs to your API.
  • API Gateway requires that you use https, but the certificate that it uses is only valid for the default domain.

There is a solution, however. Here are the steps that I followed when I recently set this up:

  1. Generate an origin certificate from the crypto tab of the Cloudflare dashboard.
  2. Import the certificate to AWS Certificate manager in the us-east-1 region, even if your API is located in a different region. If you are prompted for the certificate chain you can copy it from here.
  3. Add your custom domain in the API Gateway console and select the certificate you just added. Check the AWS support article for more information on how to do this.
  4. It usually takes about 45 minutes for the custom domain to finish initializing. Once it's done it will give you a new Cloudfront URL. Go ahead and make sure your API still works through this new URL.
  5. Go to the Cloudflare DNS tab and setup a CNAME record pointing to Cloudfront URL you just created.
  6. Switch to the crypto tab and set your SSL mode to "Full (Strict)". If you skip this step you'll get a redirect loop.

That's it. Enjoy your new highly available API served from your custom domain!

26
votes

Set up Amazon's API Gateway Custom Domain with CloudFlare

  1. In your AWS management console go to the API Gateway service and select Custom Domain Names from the left menu.

  2. Click the Create button.

  3. Log into CloudFlare, select your domain and open the Crypto tab

  4. Go to SSL and set your SSL mode to "Full (Strict)" to avoid a redirect loop.

  5. Go to Origin Certificates and click Create Certificate

  6. Let CloudFlare generate a private key and a CSR and choose RSA as the private key type

  7. Make sure that the hostname for your custom API domain is covered. (e.g. api.mydomain.com. You can specifically configure this custom domain or use a wildcard such as *.mydomain.com as is configured by default.

  8. Pick PEM as the key format which is selected by default.

  9. In AWS switch to region US-EAST-1 and goto the Certificate Manager.

  10. Click Import a Certificate.

  11. Copy the certificate body from your CloudFlare certificate to Certificate body to the configuration of the custom domain in the AWS Management Console.

  12. Copy the Private key to the certificate private key field in the console

  13. In the certificate chain copy the Cloudflare Origin CA - RSA Root which can be found here.

  14. Enter your custom domain name in the AWS console and a name for your certificate

  15. Now the custom domain name will be created in AWS CloudFront. It can take up to an hour before the domain becomes active.

  16. The next thing you need to do is set up the mappings of the custom domain in the AWS Console.

  17. The final step is to create a new CNAME Record in CloudFlare to link your domain to the CloudFront url. When you open the settings page of your custom domain in the AWS console copy the Distribution domain name. This is the domain you need to use when creating the new CNAME Record.

Source

3
votes

Both existing answers to this question are correct, but if the issue still persists even after following these directions perfectly, try going into the API Gateway settings, navigate to "Custom Domain Name" and configure the Base Path Mappings.

This was the missing step that solved all my problems.

3
votes

I couldn't get any of the other answers to work. So I ended up having AWS generate the certificate instead of using a Cloudflare Origin one. That's because AWS wouldn't accept my Cloudflare certificate, even when the chain was provided. I couldn't see Cloudflare in Mozilla's Certificate Authority list (which is what AWS relies on, according to the docs) so I guess that makes sense.


Here's the outline of my solution:

  1. Create AWS Route53 Zone
  2. Create AWS ACM Certificate (must be in us-east-1) with validation method DNS
  3. Create Cloudflare DNS Record with the output of (2)
  4. Create AWS API Gateway Domain Name
  5. Create Cloudflare DNS CNAME Record pointing '@' (root domain) to the Cloudfront domain name from step (4)
  6. Create AWS API Gateway Base Path Mapping

This should be roughly it. May this help someone. Feel free to ask questions.