A Poor-Man's Dynamic DNS with Ansible and Amazon Route53
I wanted to be able to configure a DNS hostname dynamically, but couldn’t find an easy-to-use dynamic DNS client that suited my needs. Using Ansible and Amazon Route53, I put together a quick, effective solution.
Requirements
First, you need an AWS account with a Route53 DNS zone. I followed these directions to create a subdomain.
Next, you need a remote host that accessible via SSH. On that host, install Python and the Boto library. Make sure that Boto is configured with sufficient AWS credentials to access and change your Route53 zone.
Ansible Configuration
This section was updated on 2016-11-29 to reflect improvements I’ve made in the Ansible playbook.
Ansible made this task simple. In fact, the playbook below is mostly based on example recipes from the Ansible Route53 module documentation. The YAML playbook should look like the example below. Replace YOUR-ROUTE53-ZONE
with the zone you configured in Route53. Replace YOUR-FULL-DYNAMIC-HOSTNAME
with the fully-qualified domain name that you’ll use for dynamic DNS.
Note that this uses the ipify_facts Ansible module. You can use the default value or pass api_url
like I’m doing in this example.
---
- name: Update Dynamic IP
hosts: localhost
vars:
dyn_zone: YOUR-ROUTE53-ZONE
dyn_hostname: YOUR-FULL-DYNAMIC-HOSTNAME
tasks:
- name: Get public IP
ipify_facts: api_url=https://arnesonium.com/api/yourip.php
connection: local
- name: Get existing host information
register: dynip
route53:
command: get
zone: ""
record: ""
type: A
- name: Delete existing host information
when: ipify_public_ip != dynip.set.value
route53:
command: delete
zone: ""
record: ""
ttl: ""
type: ""
value: ""
- name: Create new host record
when: ipify_public_ip != dynip.set.value
route53:
command: create
zone: ""
record: ""
type: A
ttl: 600
value: ""
Running Your Playbook
I named my playbook dyndns.yml, so I run it with this shell command:
ansible-playbook -vv dyndns.yml
The -vv
increases the verbosity so you can see what’s going on.
The Next Step
Next, I need to convince this script to run every time my laptop’s network comes back online. I’m sure there’s a good way to do that, but I haven’t spent much time looking into it.
Did this playbook work for you? Let me know! I’d love to get feedback on it.