Here's a quick post that shows how to manage
Amazon Route 53 DNS zones and records using the ever-useful
boto library from
Mitch Garnaat. Route 53 is a typical pay-as-you-go inexpensive AWS service which you can use to host your DNS zones. I wanted to play with it a bit, and some Google searches revealed two good blog posts: "
Boto and Amazon Route53" by Chris Moyer and "
Using boto to manage Route 53" by Rob Ballou. I want to thank those two guys for blogging about Route 53, their posts were a great help to me in figuring things out.
Install boto
My machine is running Ubuntu 10.04 with Python 2.6. I ran 'easy_install boto', which installed boto-2.0rc1. This also installs several utilities in /usr/local/bin, of interest to this article being /usr/local/bin/route53 which provides an easy command-line-oriented way of interacting with Route 53.
Create boto configuration file
I created ~/.boto containing the Credentials section with the AWS access key and secret key:
# cat ~./boto
[Credentials]
aws_access_key_id = "YOUR_ACCESS_KEY"
aws_secret_access_key = "YOUR_SECRET_KEY"
Interact with Route 53 via the route53 utility
If you just run 'route53', the command will print the help text for its usage. For our purpose, we'll make sure there are no errors when we run:
# route53 ls
If you don't have any DNS zones already created, this will return nothing.
Create a new DNS zone with route53
We'll create a zone called 'mytestzone':
# route53 create mytestzone.com
Pending, please add the following Name Servers:
ns-674.awsdns-20.net
ns-1285.awsdns-32.org
ns-1986.awsdns-56.co.uk
ns-3.awsdns-00.com
Note that you will have to properly register 'mytestzone.com' with a registrar, then point the name server information at that registrat to the name servers returned when the Route 53 zone was created (in our case the 4 name servers above).
At this point, if you run '
route53 ls' again, you should see your newly created zone. You need to make note of the zone ID:
root@m2:~# route53 ls
================================================================================
| ID: MYZONEID
| Name: mytestzone.com.
| Ref: my-ref-number
================================================================================
{}
You can also get the existing records from a given zone by running the '
route53 get' command which also takes the zone ID as an argument:
# route53 get MYZONEID
Name Type TTL Value(s)
mytestzone.com. NS 172800 ns-674.awsdns-20.net.,ns-1285.awsdns-32.org.,ns-1986.awsdns-56.co.uk.,ns-3.awsdns-00.com.
mytestzone.com. SOA 900 ns-674.awsdns-20.net. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
Adding and deleting DNS records using route53
Let's add an A record to the zone we just created. The route53 utility provides an 'add_record' command which takes the zone ID as an argument, followed by the name, type, value and TTL of the new record, and an optional comment. The TTL is also optional, and defaults to 600 seconds if not specified. Here's how to add an A record with a TTL of 3600 seconds:
# route53 add_record MYZONEID test.mytestzone.com A SOME_IP_ADDRESS 3600
{u'ChangeResourceRecordSetsResponse': {u'ChangeInfo': {u'Status': u'PENDING', u'SubmittedAt': u'2011-06-20T23:01:23.851Z', u'Id': u'/change/CJ2GH5O38HYKP0'}}}
Now if you run '
route53 get MYZONEID' you should see your newly added record.
To delete a record, use the 'route53 del_record' command, which takes the same arguments as add_record. Here's how to delete the record we just added:
# route53 del_record Z247A81E3SXPCR test.mytestzone.com. A SOME_IP_ADDRESS
{u'ChangeResourceRecordSetsResponse': {u'ChangeInfo': {u'Status': u'PENDING', u'SubmittedAt': u'2011-06-21T01:14:35.343Z', u'Id': u'/change/C2B0EHROD8HEG8'}}}
Managing Route 53 programmatically with boto
As useful as the route53 command-line utility is, sometimes you need to interact with the Route 53 service from within your program. Since this post is about boto, I'll show some Python code that uses the Route 53 functionality.
Here's how you open a connection to the Route 53 service:
from boto.route53.connection import Route53Connection
conn = Route53Connection()
(this assumes you have the AWS credentials in the ~/.boto configuration file)
Here's how you retrieve and walk through all your Route 53 DNS zones, selecting a zone by name:
ROUTE53_ZONE_NAME = "mytestzone.com."
zones = {}
conn = Route53Connection()
results = conn.get_all_hosted_zones()
zones = results['ListHostedZonesResponse']['HostedZones']
found = 0
for zone in zones:
print zone
if zone['Name'] == ROUTE53_ZONE_NAME:
found = 1
break
if not found:
print "No Route53 zone found for %s" % ROUTE53_ZONE_NAME
(note that you need the ending period in the zone name that you're looking for, as in "mytestzone.com.")
Here's how you add a CNAME record with a TTL of 60 seconds to an existing zone (assuming the 'zone' variable contains the zone you're looking for). You need to operate on the zone ID, which is the identifier following the text '/hostedzone/' in the 'Id' field of the variable 'zone'.
from boto.route53.record import ResourceRecordSets
zone_id = zone['Id'].replace('/hostedzone/', '')
changes = ResourceRecordSets(conn, zone_id)
change = changes.add_change("CREATE", 'test2.%s' % ROUTE53_ZONE_NAME, "CNAME", 60)
change.add_value("some_other_name")
changes.commit()
To delete a record, you use the exact same code as above, but with "DELETE" instead of "CREATE".
I leave other uses of the 'route53' utility and of the boto Route 53 API as an exercise to the reader.