A Practical Guide to AWS Custom Domains and Certificate Manager

Alexy Grabov
5 min readMay 22, 2023

--

When developing on AWS, you are presented with an easy, fully managed, and powerful ways to allow your users to interact with your application through a friendly and secure domain name.

You can create a custom Domain Name for your endpoint using AWS Custom Domain, expose it to the web using a Route53 entry and let Amazon’s best-in-class DNS make it live in 60 seconds or less.

In a fairly simple way, you can create a custom certificate through Certificate Manager, associate it with your new Domain Name — and be done with it.

However, tech is not always that simple. As much as we all love those AWS keynotes where they spin-up whole web applications using 3 lines of code, those rarely represent a real-world applicable solution.

You can often find yourself with an unreachable domain target, plagued with SSL errors, without any information as to where the problem lies.

In this practical blog I’ll guide you through the step and navigate around pitfalls that AWS fails to properly explain. I’ll also provide screen captures of AWS console and working Python code snippets.

Custom Domains

We need to distinguish between several types of domains and domain validation options. A domain can be a specific string like “www.mywebsite.com”, or a wildcard domain, like “*.mywebsite.com”. The wildcard specifies that you own and would probably like to manage sub-domains, i.e., “friend.mywebsite.com” would be considered a subdomain and will be routed to your target through Route53 (we’ll get to that in a second).

We also need to make sure we “own” the right to register a domain in AWS. For example, if you want to register some new domain for your web site, like “mysupercoolcat123.com”, it’s probably available and AWS would let you register it to your account. From this moment on you own this domain and can freely add up sub-domains to it.

Registering a custom domain in Route53

Now that we’ve done that, we need to create a Hosted Zone in Route53 (see? We got to it!) and add a route entry that would route traffic incoming to your custom domain to an API gateway, for example.

Creating a Hosted Zone for your new domain name

In most organizations, however, it’s common for a single master account to control that organization’s domain, and registering subdomains need to be validated and approved before you can use them.

This validation is performed by obtaining a valid certificate for your domain.

Certificate Manager

See, at this point, if you try accessing your new, shiny domain, you will be presented with an SSL error, as your domain is not validated by a certificate. You will need to generate a certificate for your custom domain even if you own it and it’s not managed by your organization.

The SSL matching error. Caused because AWS’ root CA is returned when a user accesses your website.

You have routed traffic from your custom domain to AWS API Gateway, which has a default AWS-issued certificate, and that default certificate does not recognize your custom domain.

To resolve this issue, we can go to AWS Certificate Manager and create a new certificate for our custom domain name. In case your AWS account owns the domain (i.e. it’s not your organization’s domain) you simply enter your domain name, and be done with it. Otherwise, you need to use one of the certificate validation options — Email or DNS.

Choosing email validation will make AWS send an email to someone in your organization, and he will be requested to approve your certificate request. Most organizations won’t use it, probably, as this is unsustainable.

from aws_cdk import aws_certificatemanager, aws_route53
from aws_cdk.aws_apigateway import DomainName, SecurityPolicy, EndpointType

cert = aws_certificatemanager.DnsValidatedCertificate(
scope=self, # construct's self
id='MyCatCertificate',
domain_name='*.mysupercoolcat123.com',
# construct's self, CatZone = HostedZone constructID, zone_name = domain name
hosted_zone=aws_route53.HostedZone(self, 'CatZone', zone_name='mysupercoolcat123.com'),
region='us-wast-1',
)

domain = DomainName(
scope=self,
id='CatsAPI',
certificate=cert,
domain_name='*morecats.mysupercoolcat123.com',
endpoint_type=EndpointType.REGIONAL,
security_policy=SecurityPolicy.TLS_1_2,
)

So, we’re choosing to validate our certificate request using DNS. This would require a couple of things from you — a Hosted Zone and DNS records that are “trusted” by the account that owns the company’s domain. Both must exist before you request to validate a certificate.

Your “main” hosted zone.
subdomain hosted zone.

There are a couple of gotchas to pay attention to here.

First, you must use the “trusted” Hosted Zone to create your DNS records for your new domain, i.e. the one you used to validate your certificate.

Second, you must use the same Hosted Zone for all sub-sub domain as well. For example, if you have a subdomain for “*.legal.mysupercoolcat123.com”, and you want to further sub it, like “*.lawyers.legal.mysupercoolcat123.com”, this entry must be validated using the “parent” hosted zone and it’s Route53 entry must also be created in its “parent” Hosted Zone.

Third, AWS have a funny way of matching wildcards. If we go back for a second to our “*.lawyers.legal.mysupercoolcat123.com” sub-sub domain, you would think that you can use your company’s main “*.mysupercoolcat123.com” domain’s certificate — but no.

You see, AWS’s Certificate Manager is matching the string up-to the first dot. So, when approving the “*.lawyers.legal.mysupercoolcat123.com” domain, it would search for an existing, validated “*.legal.mysupercoolcat123.com” domain.

To overcome this limitation, use a hyphen instead of a dot — “*.lawyers-legal.mysupercoolcat123.com

Examples of valid certificate names. They are automatically approved using DNS validation (see Python code).

Summary

You should now have the tools and know-how required for creating, managing, and validating custom domain names and certificated for those custom domains in AWS — using both the AWS console and using Python code.

We’ve covered creating a custom domain name — both account-owned and as a sub-domain of your organization’s domain.

We also covered securing the domain with a valid certificate — and how to obtain such a certificate both for your account-owned domain and when creating a subdomain inside your organization.

We talked about common configuration mistakes and possible solutions.

Happy deploying!

--

--

Alexy Grabov

Gamer first, Engineer second. Develops CyberArk’s PaaS.