Skip to content

Instantly share code, notes, and snippets.

@filipenf
Created June 27, 2016 18:21
Show Gist options
  • Select an option

  • Save filipenf/1fd5cdea4ebc8c49e6982ad27db05a2a to your computer and use it in GitHub Desktop.

Select an option

Save filipenf/1fd5cdea4ebc8c49e6982ad27db05a2a to your computer and use it in GitHub Desktop.
Updates route53 records to match the instances on autoscaling group
#!/usr/bin/env python
# Registers all instance IPs as weighted records on route53 ( and deletes the ones that aren't part of the ASG anymore )
# Example 1: will create/update/delete records for the "myservice.example.com" with currently registered ASG instances
# ./update_route53.py from_asg "my-asg" "myservice" "example.com"
# Example 2: will create/update/delete records to match the specified list of ips
# ./update_route53.py sync_records my-asg myservice example.com -i 200.200.200.201 200.200.200.202
import argh
import boto
import boto.route53
from boto.route53.record import ResourceRecordSets
def get_instance_ips(asg_name):
autoscale = boto.connect_autoscale()
ec2 = boto.connect_ec2()
groups = autoscale.get_all_groups([asg_name])
if len(groups) < 1:
raise Exception("No auto-scaling group named %s found" % asg_name)
instance_ids = [i.instance_id for i in groups[0].instances]
reservations = ec2.get_all_instances(instance_ids)
return [i.ip_address for r in reservations for i in r.instances]
@argh.arg('-i', '--ips', nargs='+', type=str)
def sync_records(prefix, domain, ips=[]):
r53conn = boto.connect_route53()
zone = [zone for zone in r53conn.get_all_hosted_zones().HostedZones if zone.Name==domain+"."][0]
if not zone:
raise Exception("Unable to find domain %s" % domain)
fqdn = '.'.join([prefix,domain])
zone_id = zone.Id.split('/')[2]
zone_records = r53conn.get_all_rrsets(zone_id)
existing_ips = set([ ip for rr in zone_records for ip in rr.resource_records if rr.name.startswith(fqdn) ])
changes = ResourceRecordSets(r53conn, zone_id)
to_delete = existing_ips - set(ips)
for ip in to_delete:
change = changes.add_change("DELETE", fqdn, "A", ttl=60, weight=1, identifier=ip)
change.add_value(ip)
to_add = set(ips) - existing_ips
for ip in to_add:
change = changes.add_change("CREATE", fqdn, "A", ttl=60, weight=1, identifier=ip)
change.add_value(ip)
if len(to_add) > 0 and len(to_delete) > 0:
changes.commit()
def from_asg(asg_name, prefix, domain):
ips = get_instance_ips(asg_name)
sync_records(prefix, domain, ips)
if __name__ == "__main__":
parser = argh.ArghParser()
parser.add_commands([sync_records, from_asg])
parser.dispatch()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment