Created
June 29, 2015 21:10
-
-
Save mtbdeano/fbd7672c04e7b4657e37 to your computer and use it in GitHub Desktop.
Simple python script to keep Amazon Route 53 public/private split horizon DNS domains in sync
This file contains 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
import boto.route53 | |
import boto.ec2 | |
import pprint as pp | |
def match_domain(domain, region="us-east-1"): | |
''' iterate through the public EIPs and make sure that if there is a `domain.com` entry for that EIP, it's private IP is also mapped in the private `domain.com` | |
''' | |
r53 = boto.route53.connect_to_region(region) | |
ec2 = boto.ec2.connect_to_region(region) | |
public_zone = None | |
private_zone = None | |
# need to make sure the domain ends with a dot | |
if domain[-1:] is not u'.': | |
domain += u'.' | |
for zone in r53.get_zones(): | |
if zone.name == domain: | |
if zone.config[u'PrivateZone'] == u'true': | |
private_zone = zone | |
else: | |
public_zone = zone | |
if public_zone is None or private_zone is None: | |
print(u'Unable to find matching {} entries'.format(domain)) | |
eips = filter(lambda eip: eip.domain == u'vpc', ec2.get_all_addresses()) | |
# route53 objects | |
public_addresses = filter(lambda r: r.type == u'A', r53.get_all_rrsets(public_zone.id)) | |
private_addresses = filter(lambda r: r.type == u'A', r53.get_all_rrsets(private_zone.id)) | |
# convenience set | |
set_of_private_addresses = set(map(lambda x: x.resource_records[0], private_addresses)) | |
# maps | |
public_to_private = {eip.public_ip: eip.private_ip_address for eip in eips} | |
public_to_name = {r.resource_records[0]: r.name for r in public_addresses} | |
# cross domain map | |
name_to_private = {name: public_to_private[public_ip] for (public_ip, name) in | |
filter(lambda (ip, name): ip in public_to_private, public_to_name.iteritems())} | |
print "name_to_private" | |
pp.pprint(name_to_private) | |
# just find the ones that don't exist | |
upsert_to_private = dict(filter(lambda (name, ip): ip not in set_of_private_addresses, name_to_private.iteritems())) | |
print "upsert_to_private" | |
pp.pprint(upsert_to_private) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This requires
boto
, but not much else. Basic logic is:with
name_to_private
being the complete list of public DNS names that require private DNS entries andupsert_to_private
as the list of names that don't already exist in Route 53 on the private side. Actually updating your domain record is left as an exercise for the reader.