Amazon Route 53 Basics
This post will kick off a series on Scalable Solutions. Entasis uses a strong architectural emphasis in our AWS Solutions Group to deliver solutions that are Elastic by nature, Resilient in design, with Performance on demand. These are the three pillars of Scalable Solutions. In this series, we will be going through some of the architectural components and decisions which allow us to design and deliver all three of these pillars in our solutions.
Today we will be discussing interacting with Route 53 from a basic level. Route 53 has many advanced components such as failover records, weighted records, geolocated records and aliases. These will be covered in a later article.
Later in the series, we will also cover Amazon Certificate Manager, Elastic Load Balancer (application), and AWS System Manager (Parameter Store).
Whenever interacting with Route 53 records we are forced to use JSON to make changes, which can complicate the process if you are using the AWS CLI on Powershell as I am. Your mileage will vary if you are using bash or cygwin to use the AWS CLI.
Check Change Status
Everything that we do in Route 53 gets submitted as a change that can then be monitored. Though we haven’t actually covered any changes this is really the critical thing to understand, so we will cover it first, feel free to refer back to this as needed.
PS> aws route53 get-change –id C2UR6HOGT6QLD8<br />
{<br />
"ChangeInfo": {<br />
"Status": "INSYNC",<br />
"SubmittedAt": "2018-06-29T19:29:41.148Z",<br />
"Id": "/change/C2UR6HOGT6QLD8"<br />
}<br />
}
The Status of INSYNC indicates that the change has been rolled out across the environment, PENDING indicates that the change is still being rolled out across the environment.
Create Hosted Zone
One of the basic functions of Route 53 is to create a hosted zone. The one tricky component here is the caller-reference which is required, this just needs to be a unique string, here we are using Get-Date for a timestamp.
PS> aws create-hosted-zone –name squirrelbox.io –caller-reference (Get-Date)<br />
{<br />
"HostedZone": {<br />
"ResourceRecordSetCount": 2,<br />
"CallerReference": "06/29/2018 14:23:54",<br />
"Config": {<br />
"PrivateZone": false<br />
},<br />
"Id": "/hostedzone/Z1XXXXXXXXXF2",<br />
"Name": "squirrelbox.io."<br />
},<br />
"DelegationSet": {<br />
"NameServers": [<br />
"ns-1826.awsdns-36.co.uk",<br />
"ns-714.awsdns-25.net",<br />
"ns-1417.awsdns-49.org",<br />
"ns-248.awsdns-31.com"<br />
]<br />
},<br />
"Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z1XXXXXXXXXF2",<br />
"ChangeInfo": {<br />
"Status": "PENDING",<br />
"SubmittedAt": "2018-06-29T19:23:55.689Z",<br />
"Id": "/change/C30WD325YLHTWA"<br />
}<br />
}
You can then check the status of the change created.
Get Hosted Zone ID with Zone Name
In order to interact with Route 53 we are going to need to have the zone id. This snippet is a simple way to get the zone id based off of the domain name.
PS> (aws route53 list-hosted-zones | ConvertFrom-Json)."HostedZones" | where { $_.Name -eq "itfromallangles.com." }</p>
<p>ResourceRecordSetCount : 19<br />
CallerReference : B08E4F7D-A48E-7938-ADF0-1DCD08D96B9E<br />
Config : @{Comment=Zone Comments Here; PrivateZone=False}<br />
Id : /hostedzone/ZKXXXXXXXXX0S<br />
Name : itfromallangles.com.
Here we see the zone id, whenever you interact with a zone it is by zone id. You will need to know how to get this id.
Get Hosted Zone Details with Zone Name
This command is really a shortcut demonstration of using a single command to pull the zone id based on the zone name and then use that inline in another command (in this case it is get-hosted-zone).
PS> aws route53 get-hosted-zone –id ((aws route53 list-hosted-zones | ConvertFrom-Json)."HostedZones" | where { $_.Name -eq "itfromallangles.com." }).Id<br />
{<br />
"HostedZone": {<br />
"ResourceRecordSetCount": 17,<br />
"CallerReference": "B08E4F7D-A48E-7938-ADF0-1DCD08D96B9E",<br />
"Config": {<br />
"Comment": "Zone Comments Here",<br />
"PrivateZone": false<br />
},<br />
"Id": "/hostedzone/ZKXXXXXXXXX0S",<br />
"Name": "itfromallangles.com."<br />
},<br />
"DelegationSet": {<br />
"NameServers": [<br />
"ns-994.awsdns-60.net",<br />
"ns-1380.awsdns-44.org",<br />
"ns-325.awsdns-40.com",<br />
"ns-1604.awsdns-08.co.uk"<br />
]<br />
}<br />
}
Understand what we have done above and this will save you a ton of time on the CLI interacting with Route 53.
Delete Hosted Zone with Zone Name
Now let’s delete a hosted zone.
PS> aws route53 delete-hosted-zone –id ((aws route53 list-hosted-zones | ConvertFrom-Json)."HostedZones" | where { $_.Name -eq "squirrelbox.io." }).Id { "ChangeInfo": { "Status": "PENDING", "SubmittedAt": "2018-06-29T19:29:41.148Z", "Id": "/change/C2UR6HOGT6QLD8" } }
You can then check the status of the change created.
Build Change Set for Validation Record
Now we are going to start updating or creating zones.
Here is where Powershell starts to make our lives difficult. Powershell doesn’t directly interact with JSON so we have to build the JSON as a series of hash tables and arrays and then convert that into valid JSON. To simplify this process I use a hash table to make editing it easier from change to change. Notice the name, I have found two scenarios which will work. The first is monkey.itfromallangles.com (fully qualified, with no period), the second is monkey.itfromallangles.com. (fully qualified, with a period). If you try and do “monkey” then it will not work as it will see it as a fully qualified name of monkey. (with a period) which wouldn’t be a valid record in itfromallangles.com.
$record = @{ Name = ‘monkey.itfromallangles.com.’; Value = ‘1.1.1.1’; Type = ‘A’ }
Now lets validate our hashtable.
$record</p>
<p>Name Value<br />
—- —–<br />
Type A<br />
Name monkey.itfromallangles.com.<br />
Value 1.1.1.1
Now lets look at the individual entries.
PS> $record.Name<br />
monkey.itfromallangles.com.<br />
PS> $record.Type<br />
A<br />
PS> $record.Value<br />
1.1.1.1
Next we are going to populate the change set. We are using the UPSERT action which is an INSERT or UPDATE if necessary.
PS> @{<br />
Changes = @(<br />
@{<br />
Action = ‘UPSERT'<br />
ResourceRecordSet = @{<br />
Name = $record.Name<br />
Type = $record.Type<br />
TTL = 300<br />
ResourceRecords = @(<br />
@{<br />
Value = $record.Value<br />
}<br />
)<br />
}<br />
})<br />
} | ConvertTo-Json -Depth 5 -Compress | Out-File $env:TEMP\route53change.json -Encoding ASCII
This will create a JSON file which we will use to change the record in the zone.
Create Change Resource Record Sets Request
Here we will lookup the zone id based off of the zone name. Then request the change for that zone.
PS> aws route53 change-resource-record-sets –hosted-zone-id ((aws route53 list-hosted-zones | ConvertFrom-Json)."HostedZones" | where { $_.Name -eq "itfromallangles.com." }).Id –change-batch file://$env:TEMP\route53change.json<br />
{<br />
"ChangeInfo": {<br />
"Status": "PENDING",<br />
"SubmittedAt": "2018-06-29T18:37:47.352Z",<br />
"Id": "/change/CR7IMAZ69UJEO"<br />
}<br />
}
We now have a change id which we can use to monitor the status of the change roll out.
Conclusion
Route 53 is a very effective DNS product which allows you to build complex automation into your solutions, in a later article we will discuss some more complicated Route 53 operations such as domain registration, as well as the more complicated record sets such as failover, weighted and alias records. Using these components properly in your architecture will add a significant amount of resiliency and self-healing to your deployments.
If you would like to talk about your specific use-case we would love to help. Please email us at sales@entasistech.com.