Standardizing the Zone
23.02.2021, last updated 05.03.2021 - Jeremy T. Bouse - ~8 Minutes
Let’s talk about zones
When starting out with a new domain you have certain expectations that Route53 handles automatically for you, like the NS and SOA records which come by default. That is just the bare minimum to get you going though, you’ll need a lot more than that as you expect to the domain into use.
|
|
How about an S3 bucket, or two?
When working within AWS it is generally a good idea to create an S3 bucket with the same name as your domain. The big reason for this is that since S3 is a global namespace ANYONE can create a bucket and the first one to do so gets it. Where this becomes a problem is if you own the domain but not the S3 bucket, you can then lose control of your website if you decide to host a static website from S3. I have seen in the past where organizations setup an S3 static website for their domain in a bucket that doesn’t match their site hostname, maybe they put it behind CloudFront, and things work until someone detects the bucket for that hostname doesn’t exist and decides to create the bucket and put up a fake site that is suddenly now presented to viewers.
|
|
So I find it is best to just go ahead and create a bucket for my zone, and
while I’m at it I also setup the traditional www.domain
bucket as well and
configure them both as static website buckets with the www.domain
bucket set
to redirect to domain
. While this prevents someone else from being able to take
the bucket name of your domain, it also gives you a great starting point as you
begin to setup your new domain’s web presence as you could then just put a simple
“Coming Soon!” index.html page in the domain
bucket.
|
|
Though to get that page to be seen you have to have a DNS Resource Record created that points to the S3 static website. This could be done when creating the zone and S3 buckets initially but I refrain from doing so as more than likely I’ll have another deployment and I don’t want competing deployments trying to change the record on me.
Are we going to use certificates?
Most current Certificate Authorities (CA) will now check for a Certificate Authority Authorization or CAA DNS record in your domain zone. This is simply a record that states your public policy for whom can issue SSL/TLS certificates for your domain. Not all CAs support CAA records but the number of those that do are increasing and include most of the reputable ones. Amazon Certificate Manager (ACM) and Let’s Encrypt both support CAA lookups. With the increasing threat of malicious actors any extra level of security is good so when setting up my zone I also include a CAA record limiting to the CAs I will use, which invariably includes Amazon.
|
|
Sending email considerations
With a domain you are undoubtably going to want to be able to send email messages and within Amazon the easiest way to do that is using Simple Email Service . Properly setting this up now ensures it is ready to use when you need it, even if you have email service being handled somewhere else this will ensure you can send message reliably out of AWS. When I set this up for my zones I also include configuring it with DKIM authentication and bounce & complaint notifications via an SNS topic along with the requisite DNS records. In my Terraform deployment I’ve actually split this off into it’s own module, there are others out there on the Terraform Registry that you can evaluate though I consider mine to be fairly complete for the task at hand.
First we request a domain identity and then domain DKIM generation for the domain. The domain identity resource will then give us a verification token to prove ownership and we will receive 3 DKIM tokens to setup from the domain DKIM resource.
|
|
Next we need to verify we control the domain with the verification token we received and setup the 3 DKIM tokens in our new zone.
|
|
The next piece required to finish setting up SES for our domain is to setup the
DNS records that Amazon expects to find. We will request SES use the MAIL FROM
to be used as bounce.domain
and Amazon will require us to setup an MX record
to receive those bounce messages and an SPF TXT record for this MX. As this is
only for receiving bounce messages the SPF record does not need to be modified.
|
|
You may note that I included the allow_overwrite
setting to true which tells
Terraform to overwrite these records in Route53 if they exist. As this should
authoritative for these records and nothing else should be setting them this
should be okay.
While optional, it is a good idea to be sure you stay aware of any complaints or bounces received by Amazon when using SES as these can limit your ability to use the service if the rate becomes too high. You can additionally setup CloudWatch alerts on an account level as these metrics are not per zone. If you have an existing SNS topic you can use that rather than creating a new one. I leave it with only Bounce and Complaint notification types, there is a third Delivery which you could enable while getting started but once active and if it sends any amount of email could be unnecessary noise so I don’t enable it.
|
|
If you didn’t use an existing SNS topic and created a new one as the template above
demonstrates then you will need to create a subscription to receive the notifications.
Unfortunately due to the verification steps to accept the subscription Terraform
is unable to handle email
or email-json
subscriptions to a topic though if you
had a SQS, Lambda function or an HTTP/HTTPS application that received your alerts
you could add an aws_sns_topic_subscription
resource.
With this in place we have a Route53 Hosted Zone baseline to begin working from. On top of this I would then add my MTA-STS and DMARC settings which I will go over in another post so check back again for that update. With this solution I wrap it all up in a git repository and create a Terraform Cloud workspace for each of my zones with version control workflow. Operating it in this way, if I make a change to my zone template it is applied to all of my zones uniformly which afterall is the whole goal of this exercise.