Last active
November 22, 2021 23:06
-
-
Save ngoue/fae88aefb2eca5f6a489cd037c1a34ff to your computer and use it in GitHub Desktop.
Dynamic DNS with Route53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
""" | |
Dynamic DNS - Route53 | |
Check the current IP address for this device and compare it with the DNS record | |
in Route53. If it's different, update the DNS record! | |
""" | |
import logging | |
import os | |
import re | |
import sys | |
import boto3 | |
import requests | |
logging.basicConfig( | |
format="%(asctime)s %(levelname)-8s %(message)s", | |
level=logging.INFO, | |
datefmt="%Y-%m-%d %H:%M:%S" | |
) | |
LOG = logging.getLogger('dynamic-dns') | |
RE_IP_ADDRESS = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') | |
HOSTED_ZONE_ID = os.getenv('HOSTED_ZONE_ID') | |
RECORD_NAME = os.getenv('RECORD_NAME') | |
if __name__ == '__main__': | |
LOG.debug('Starting dynamic-dns') | |
# Require HostedZone ID | |
LOG.debug('Verifying HostedZone ID') | |
if HOSTED_ZONE_ID is None: | |
LOG.warning('Missing HostedZone ID') | |
sys.exit(1) | |
# Require HostedZone ID | |
LOG.debug('Verifying record name') | |
if RECORD_NAME is None: | |
LOG.warning('Missing record name') | |
sys.exit(1) | |
# Check the current public IP address | |
LOG.debug('Retrieving current public IP address') | |
current_ip = requests.get('http://checkip.amazonaws.com').text.strip() | |
LOG.debug('Current public IP address: %s', current_ip) | |
# Validate the current public IP address | |
LOG.debug('Validating current public IP address') | |
if not RE_IP_ADDRESS.match(current_ip): | |
LOG.warning('Invalid IP address: %s', current_ip) | |
sys.exit(2) | |
# Cross-check the current DNS record | |
LOG.debug('Retrieving current DNS') | |
route53 = boto3.client('route53') | |
all_records = route53.list_resource_record_sets( | |
HostedZoneId=HOSTED_ZONE_ID | |
).get('ResourceRecordSets', []) | |
current_record = None | |
for record in all_records: | |
if record['Name'] == RECORD_NAME: | |
current_record = record | |
break | |
# Check for changes | |
LOG.debug('Checking current DNS against current IP address') | |
if current_record['ResourceRecords'][0]['Value'] == current_ip: | |
LOG.info('DNS is up-to-date. Exiting...') | |
sys.exit() | |
# Update the DNS | |
LOG.debug('Updating DNS') | |
route53.change_resource_record_sets( | |
HostedZoneId=HOSTED_ZONE_ID, | |
ChangeBatch={ | |
'Comment': 'Updated using dynamic_dns_route53.py', | |
'Changes': [{ | |
'Action': 'UPSERT', | |
'ResourceRecordSet': { | |
'Name': record['Name'], | |
'Type': record['Type'], | |
'TTL': 300, | |
'ResourceRecords': [{ | |
'Value': current_ip | |
}] | |
} | |
}] | |
} | |
) | |
LOG.info('Updated DNS successfully: %s', current_ip) | |
sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instructions
pip3 install requests boto3