Updating Route53 DNS dynamically

If you are using Route53 for DNS, it is pretty easy to update a route 53 DNS record with your current IP address as a dynamic DNS service. Here is a script that does so. It

  • Looks up your current IP address
  • Looks up the IP address in DNS for your host name
  • Uses the AWS command line client to update the DNS record if it needs to be changed

set -e

# The host name for which you want to change the DNS IP address
# The AWS id for the zone containing the record, obtained by logging into aws route53
# The name server for the zone, can also be obtained from route53
# Optional -- Uncomment to use the credentials for a named profile
#export AWS_PROFILE=examplecom

# Get your external IP address using opendns service
newip=`dig +short myip.opendns.com @resolver1.opendns.com`
if [[ ! $newip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
    echo "Could not get current IP address: $newip"
    exit 1

# Get the IP address record that AWS currently has, using AWS's DNS server
oldip=`dig +short "$hostname" @"$nameserver"`
if [[ ! $oldip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
    echo "Could not get old IP address: $oldip"
    exit 1

# Bail if everything is already up to date
if [ "$newip" == "$oldip" ]
    exit 0

# aws route53 client requires the info written to a JSON file
tmp=$(mktemp /tmp/dynamic-dns.XXXXXXXX)
cat > ${tmp} << EOF
    "Comment": "Auto updating @ `date`",
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "ResourceRecords":[{ "Value": "$newip" }],
            "Name": "$hostname",
            "Type": "A",
            "TTL": 300

echo "Changing IP address of $hostname from $oldip to $newip"
aws route53 change-resource-record-sets --hosted-zone-id $zoneid --change-batch "file://$tmp"

rm "$tmp"

This is based on the code from Will Warren but it has some changes:

  • It doesn’t rely on a local file to store what the set the IP address, it looks it up from the AWS DNS server
  • It has fewer configuration options at the top (just three required and one optional)
  • It doesn’t do any logging, it simply exits with no output or prints changes to stdout. This makes it more suitable for running from cron with emailed output
  • The code has been cleaned up and streamlined

It can then be put into a crontab. For example create /etc/cron.d/dynamicdns to execute it once an hour:

49 * * * * root   /opt/dynamicdns.sh


Leave a comment

Your email address will not be published. Required fields are marked *