Created
July 10, 2018 07:37
-
-
Save kshcherban/256bae174637d9b2cae7c2fb5aeddbe0 to your computer and use it in GitHub Desktop.
Script to upgrade autoscaling group
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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import boto3 | |
from multiprocessing.dummy import Pool as ThreadPool | |
import sys | |
import time | |
group_name = sys.argv[1] | |
ag = boto3.client('autoscaling') | |
def terminate_instance(instance, repeat=60): | |
""" Repeat terminating call N times """ | |
if repeat == 0: | |
print('Maximum waiting time exceeded for {0}'.format(instance)) | |
return | |
else: | |
try: | |
response = ag.terminate_instance_in_auto_scaling_group( | |
InstanceId=instance, | |
ShouldDecrementDesiredCapacity=False) | |
except Exception: | |
return | |
if response['Activity']['StatusCode'] != 'Successful': | |
print('Termintating {0}, status {1}'.format( | |
instance, response['Activity']['StatusCode'])) | |
print('Sleeping 10s, round {0}, instance {1}'.format(repeat, instance)) | |
repeat -= 1 | |
time.sleep(10) | |
terminate_instance(instance, repeat) | |
else: | |
return | |
# Find attached launch configuration | |
try: | |
ag_data = ag.describe_auto_scaling_groups( | |
AutoScalingGroupNames=[group_name] | |
)['AutoScalingGroups'][0] | |
except IndexError: | |
print('AG {0} not found'.format(group_name)) | |
sys.exit(1) | |
lauch_config = ag_data['LaunchConfigurationName'] | |
print('AG {0} has launch configuration {1}'.format(group_name, lauch_config)) | |
instance_ids = [i['InstanceId'] for i in ag_data['Instances']] | |
# Find instances with wrong launch configuration | |
instance_data = ag.describe_auto_scaling_instances( | |
InstanceIds=instance_ids, | |
MaxRecords=50 | |
)['AutoScalingInstances'] | |
to_replace = [] | |
for i in instance_data: | |
try: | |
if i['LaunchConfigurationName'] != lauch_config: | |
print('{0} changes from {1}'.format(i['LaunchConfigurationName'])) | |
print('{0} will be replaced'.format(i['InstanceId'])) | |
to_replace.append(i['InstanceId']) | |
except KeyError: | |
print('{0} will be replaced'.format(i['InstanceId'])) | |
to_replace.append(i['InstanceId']) | |
print('Totally {0} instances will be replaced'.format(len(to_replace))) | |
# terminate instances one by one, TODO implement batches | |
threadPool = ThreadPool(processes=2) | |
threadPool.map(terminate_instance, to_replace) | |
threadPool.close() | |
threadPool.join() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment