"""DNS Lambda function module.""" import os import boto3 # Set variables STACK_NAME = os.environ['stack_name'] DOMAIN_NAME = os.environ['domain_name'] ZONE_ID = os.environ['zone_id'] TTL_SECONDS = os.environ.get('ttl_seconds', 300) def handler(event, context): """Lambda entry point.""" route53 = boto3.client('route53') compute = boto3.client('ec2') autoscaling = boto3.client('autoscaling') print( 'Autoscaling Group: "' + event['detail']['AutoScalingGroupName'] + '"') print('Autoscaling Event: "' + event['detail-type'] + '"') # Run if we're processing a launch or terminate event: if (event['detail-type'] == 'EC2 Instance Launch Successful') or ( event['detail-type'] == 'EC2 Instance Terminate Successful'): print( 'Handling ' + event['detail-type'] + ' Event for ' + event['detail']['AutoScalingGroupName']) # Get details about the autoscaling-group: print('Retrieving ASG details ...') # Look up the autoscaling group: try: auto_scaling_group = autoscaling.describe_auto_scaling_groups( AutoScalingGroupNames=[ event['detail']['AutoScalingGroupName'], ], MaxRecords=1 ) except Exception as e: print('Unable to find ASG:', e) print('Auto scaling group name: {}'.format( event['detail']['AutoScalingGroupName'])) raise e route53_meta = {} route53_meta['stackName'] = STACK_NAME print('Stack Name: "' + route53_meta['stackName'] + '"') route53_meta['domainName'] = DOMAIN_NAME print('Domain Name: "' + route53_meta['domainName'] + '"') route53_meta['zoneId'] = ZONE_ID print('R53 Zone ID: "' + route53_meta['zoneId'] + '"') # Build a list of running instances: print('Finding running instances ...') instance_ids = [] # Find instances which are running: print(auto_scaling_group) for group in auto_scaling_group['AutoScalingGroups']: for instance in group['Instances']: if instance['LifecycleState'] == 'InService': instance_ids.append(instance['InstanceId']) # Make sure we found some running instances: instance_len = len(instance_ids) if instance_len == 0: print('No running instances were found!') raise SystemExit else: print('Running instances: ') print(instance_ids) # Retrieve instance metadata: print('Getting instance metadata ...') # Describe the instances for this autoscaling group: ec2_meta = compute.describe_instances( DryRun=False, InstanceIds=instance_ids ) # Build DNS address-mappings: print('Building address-mappings for DNS records ...') address_mappings = {} region_wide_name = ( route53_meta['stackName'] + '.' + route53_meta['domainName']) print('Region wide name: ' + region_wide_name) address_mappings[region_wide_name] = [] print(ec2_meta) for reservation in ec2_meta['Reservations']: private_ip = reservation['Instances'][0]['PrivateIpAddress'] address_mappings[region_wide_name].append({'Value': private_ip}) print(address_mappings) # Create DNS records in Route53: print('Creating DNS records ...') change_resource_record_sets_request = { 'Changes': [] } # Iterate through all of the record-names in addressMappings: for record_name, record_value in address_mappings.items(): # Add a change to the changeBatch: change_resource_record_sets_request['Changes'].append( { 'Action': 'UPSERT', 'ResourceRecordSet': { 'Name': record_name, 'Type': 'A', 'TTL': TTL_SECONDS, 'ResourceRecords': record_value } } ) print(change_resource_record_sets_request) # Submit the changeResourceRecordSets() request to Route53: try: route53.change_resource_record_sets( HostedZoneId=route53_meta['zoneId'], ChangeBatch=change_resource_record_sets_request ) print('DNS has been updated for an autoscaling event') except Exception as e: print('Unable to update DNS for an autoscaling event:', e) else: print('Unsupported ASG event: "' + event['detail-type'] + '"') print('Finished')