Adding a Custom Domain to AWS API Gateway
Tags: aws, api, oas
Published: 2021-01-21 12:58:44

---
title: Adding a Custom Domain to AWS API Gateway
published: true
description: AWS is all about API development. But one thing that's harder than it should be is putting an API behind a custom domain.
tags: 
  - aws
  - api
  - oas
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/9fze1ss3t0z4f1xa6v82.jpg
canonical_url: https://www.readysetcloud.io/blog/allen.helton/adding-a-custom-domain-to-aws-api-gateway/
---

I am a big fan of side projects. I try to work on one almost every single day.

There are some side projects that get further than others, of course. Some I lose interest in quickly, some serve their purpose and I'm done with, but others I get really excited about. I want to share them with people.

Sure, I can link to my source code in [GitHub](https://www.github.com/allenheltondev), but that isn't always enough. Sometimes I want to share the finished product.

I can share the link to the implementation in a blog post. But by default APIs in AWS have some crazy names. Names that I would consider *undiscoverable*. Certainly not rememberable. 

I want somebody to remember how to get to these projects without finding my blog post. Those projects call for a **custom domain**.

In AWS, you can purchase domain names at competitive prices (and they don't jump on you after a year like most providers). The acquisition is easy and even easier to implement it with services like [AWS Amplify](https://docs.amplify.aws/). I've even written about [how easy it is](/blog/allen.helton/how-to-build-your-blog-with-aws-and-hugo) when setting up a personal blog.

However if your project is an API, setting up a custom domain might be a little confusing. There are a few pieces to the puzzle and it isn't inherently obvious what to do when you're setting it up.

So today I'm going to walk you through putting a custom domain on my fictional business - *Gopher Holes Unlimited*, which is a side project I built to illustrate proper use of [Open API Spec 3.0 (OAS)](https://openapis.org). With proper use of OAS you can take advantage of the [Postman contract test generator](/blog/allen.helton/dynamic-test-generation-with-oas) I built.

## Purchase Your Custom Domain
As I mentioned earlier, AWS makes it pretty easy to purchase domain names with their [Route 53 service.](https://aws.amazon.com/route53/). We're going to use that method to purchase our domain today.

When you navigate to the Route 53 console, you are presented with a box right in the center of the screen to search for domain name availability. 

![Searching for domain name availability in Route 53](https://readysetcloud.s3.amazonaws.com/domain_1.jpg)
*Searching for our domain name availability*

Once we search for the domain name, we can pick it out from the results page. The console walks us through a few registration steps and talks about cost and all that fun registration goodness.

Follow the wizard, confirm your purchase, and you are presented with a successful registration screen.

![Successful registration screen in Route 53](https://readysetcloud.s3.amazonaws.com/domain_2.jpg)
*Success!*

From here, AWS takes on the work to actually register the domain and do some initial setup. It will do some work behind the scenes and notify you when it's completed. For gopherholesunlimited.com it took about 15 minutes to receive an email stating the registration was successful and the domain was live.

## Create the ACM Certificate
[AWS Certificate Manager (ACM)](https://aws.amazon.com/certificate-manager/) is a service that provisions and manages SSL certificates on AWS. This is a prerequisite if we want to do anything custom domain related in API Gateway. 

Navigating to the [ACM console](https://console.aws.amazon.com/acm/home?region=us-east-1#/firstrun/), we are presented with two options: **Provision certificates** and **Private certificate authority**. For our use case we want to provision a certificate, so we navigate there and start walking through the wizard. 

Our domain name is available to the public, so we want to choose *Request a public certificate* from the available options and hit **Request a certificate**.

On the **Add domain names** screen, provide the domain name you just purchased and any subdomains you wish to secure. 

*Tip - if you want to secure all subdomains, you can use an asterisk as a wildcard,* **.gopherholesunlimited.com*.

![Configuring ACM certificate with our custom domain](https://readysetcloud.s3.amazonaws.com/domain_4.jpg)
*Adding our custom domain and subdomains to the certificate*

On the next step, choose the validation method. In our case, we want to *validate using DNS* since we have access to the hosted zone for our domain via Route 53.

You may optionally add tags and review the configuration before requesting the certificate. Once complete, you will be presented with *DNS verification records* for your domain and subdomains. 

![DNS verification records for ACM](https://readysetcloud.s3.amazonaws.com/domain_5.jpg)
*DNS verification records for ACM*

Since our domain is registered with Route 53, AWS offers to add the DNS records on our behalf. With a simple click of a button, the DNS records are added and we verified we are the owners of that domain!

## Configure the API Gateway Custom Domain
Next step in our adventure is to configure the custom domain in [API Gateway](https://aws.amazon.com/api-gateway/). In the API Gateway console, you have the option to [manage custom domains](https://console.aws.amazon.com/apigateway/main/publish/domain-names). 

Create a custom domain that matches what was added in the ACM certificate. Our project today is mapping a custom domain to an API, so we're going to use the api subdomain we created.

![Custom domain configuration in API Gateway](https://readysetcloud.s3.amazonaws.com/domain_6.jpg)
*Completed form for a new custom domain name in API Gateway*

This form is simple, you only need to fill out what subdomain/domain you want to add and select the newly created ACM certificate. Since both the root domain and the subdomain are on the same certificate, you should only see one option in the *ACM certificate* picker.

Leave the other values defaulted, add optional tags, and hit **Create domain name**.

## Create API Mappings
In the details section of the new custom domain, we are going to configure the **API mappings**. This will allow us to point the custom domain at an existing API Gateway configured in our AWS account. 

Click on the API mappings tab, then the **Configure API mappings** button to set up which APIs you want to configure.

![API mapping the new custom domain](https://readysetcloud.s3.amazonaws.com/domain_7.jpg)
*API mapping configuration for the new custom domain*

On the next screen, we are presented with a simple mapping that lets us point API stages at specific paths. This is a useful feature if you have multiple APIs making up a suite that you want behind a shared domain. 

![Configured APIs on the mapping screen](https://readysetcloud.s3.amazonaws.com/domain_8.jpg)
*The Gopher Holes Unlimited API is all wired up!*

For example if you had a shopping app, you might have separate APIs for *orders*, *charges*, and *payments*. In this case, you would want to set up your API mappings to point to the Order API at the *order* path, the Charges API at the *charges* path, and the Payments API at the *payments* path.

But in our case, we have just one API so we won't configure a path and let it live at the root of the subdomain.

## Update DNS for the Custom Domain
With the custom domain all wired up for API mappings, the last step is to update DNS records to point at the API Gateway custom domain.

On the custom domain detail page in the **Configurations** tab, you will see the *API Gateway domain name*. We need to update our DNS records to route any traffic targeted at *api.gopherholesunlimited.com* to go to this address

![Details about the custom domain we created in API Gateway](https://readysetcloud.s3.amazonaws.com/domain_9.jpg)
*Take a note of the API Gateway domain name*

With the API Gateway domain name copied to our clipboard, we need to head back over to Route 53 to [update our hosted zone](https://console.aws.amazon.com/route53/v2/hostedzones).

Once in the hosted zone, click on **Create record** to enter in the details.

![CNAME record from the subdomain to the API Gateway domain name](https://readysetcloud.s3.amazonaws.com/domain_10.jpg)
*CNAME record from the subdomain to the API Gateway domain name*

Create a CNAME record with the subdomain we chose in API Gateway - in our case *api*. For the **value**, paste in the API Gateway domain name. 

With all this setup, click **Create records** and the custom domain will officially be mapped to the API Gateway!

## Wrap Up Loose Ends
With the custom domain now pointed at our API, the hard work is done! At this point it's just wrapping up all the little things like API documentation, readme files, and Open API Specifications.

The purpose of this example is to illustrate how to use Open API Spec with the Postman contract test generator, so we need to update the `servers` property in our OAS to point to the custom domain.

![Updated server details in Open API Specification](https://readysetcloud.s3.amazonaws.com/domain_3.jpg)
*Updated server details in Open API Specification*

That's all there is to it! 

If you are interested in Gopher Holes Unlimited, check out the [GitHub repo](https://github.com/allenheltondev/gopher-holes-unlimited). Also, feel free to check out the brand new API at https://api.gopherholesunlimited.com!

Have fun out there building APIs. I hope this tutorial helped you get past any issues and roadblocks.

Good luck!