@ -394,6 +394,106 @@ ASG_ATTRIBUTES = ('AvailabilityZones', 'DefaultCooldown', 'DesiredCapacity',
INSTANCE_ATTRIBUTES = ( ' instance_id ' , ' health_status ' , ' lifecycle_state ' , ' launch_config_name ' )
INSTANCE_ATTRIBUTES = ( ' instance_id ' , ' health_status ' , ' lifecycle_state ' , ' launch_config_name ' )
backoff_params = dict ( tries = 10 , delay = 3 , backoff = 1.5 )
@AWSRetry.backoff ( * * backoff_params )
def describe_autoscaling_groups ( connection , group_name ) :
pg = connection . get_paginator ( ' describe_auto_scaling_groups ' )
return pg . paginate ( AutoScalingGroupNames = [ group_name ] ) . build_full_result ( ) . get ( ' AutoScalingGroups ' , [ ] )
@AWSRetry.backoff ( * * backoff_params )
def deregister_lb_instances ( connection , lb_name , instance_id ) :
connection . deregister_instances_from_load_balancer ( LoadBalancerName = lb_name , Instances = [ dict ( InstanceId = instance_id ) ] )
@AWSRetry.backoff ( * * backoff_params )
def describe_instance_health ( connection , lb_name , instances ) :
params = dict ( LoadBalancerName = lb_name )
if instances :
params . update ( Instances = instances )
return connection . describe_instance_health ( * * params )
@AWSRetry.backoff ( * * backoff_params )
def describe_target_health ( connection , target_group_arn , instances ) :
return connection . describe_target_health ( TargetGroupArn = target_group_arn , Targets = instances )
@AWSRetry.backoff ( * * backoff_params )
def suspend_asg_processes ( connection , asg_name , processes ) :
connection . suspend_processes ( AutoScalingGroupName = asg_name , ScalingProcesses = processes )
@AWSRetry.backoff ( * * backoff_params )
def resume_asg_processes ( connection , asg_name , processes ) :
connection . resume_processes ( AutoScalingGroupName = asg_name , ScalingProcesses = processes )
@AWSRetry.backoff ( * * backoff_params )
def describe_launch_configurations ( connection , launch_config_name ) :
pg = connection . get_paginator ( ' describe_launch_configurations ' )
return pg . paginate ( LaunchConfigurationNames = [ launch_config_name ] ) . build_full_result ( )
@AWSRetry.backoff ( * * backoff_params )
def create_asg ( connection , * * params ) :
connection . create_auto_scaling_group ( * * params )
@AWSRetry.backoff ( * * backoff_params )
def put_notification_config ( connection , asg_name , topic_arn , notification_types ) :
connection . put_notification_configuration (
AutoScalingGroupName = asg_name ,
TopicARN = topic_arn ,
NotificationTypes = notification_types
)
@AWSRetry.backoff ( * * backoff_params )
def del_notification_config ( connection , asg_name , topic_arn ) :
connection . delete_notification_configuration (
AutoScalingGroupName = asg_name ,
TopicARN = topic_arn
)
@AWSRetry.backoff ( * * backoff_params )
def attach_load_balancers ( connection , asg_name , load_balancers ) :
connection . attach_load_balancers ( AutoScalingGroupName = asg_name , LoadBalancerNames = load_balancers )
@AWSRetry.backoff ( * * backoff_params )
def detach_load_balancers ( connection , asg_name , load_balancers ) :
connection . detach_load_balancers ( AutoScalingGroupName = asg_name , LoadBalancerNames = load_balancers )
@AWSRetry.backoff ( * * backoff_params )
def attach_lb_target_groups ( connection , asg_name , target_group_arns ) :
connection . attach_load_balancer_target_groups ( AutoScalingGroupName = asg_name , TargetGroupARNs = target_group_arns )
@AWSRetry.backoff ( * * backoff_params )
def detach_lb_target_groups ( connection , asg_name , target_group_arns ) :
connection . detach_load_balancer_target_groups ( AutoScalingGroupName = asg_name , TargetGroupARNs = target_group_arns )
@AWSRetry.backoff ( * * backoff_params )
def update_asg ( connection , * * params ) :
connection . update_auto_scaling_group ( * * params )
@AWSRetry.backoff ( * * backoff_params )
def delete_asg ( connection , asg_name , force_delete ) :
connection . delete_auto_scaling_group ( AutoScalingGroupName = asg_name , ForceDelete = force_delete )
@AWSRetry.backoff ( * * backoff_params )
def terminate_asg_instance ( connection , instance_id , decrement_capacity ) :
connection . terminate_instance_in_auto_scaling_group ( InstanceId = instance_id ,
ShouldDecrementDesiredCapacity = decrement_capacity )
def enforce_required_arguments ( module ) :
def enforce_required_arguments ( module ) :
''' As many arguments are not required for autoscale group deletion
''' As many arguments are not required for autoscale group deletion
@ -471,7 +571,7 @@ def get_properties(autoscaling_group, module):
def elb_dreg ( asg_connection , module , group_name , instance_id ) :
def elb_dreg ( asg_connection , module , group_name , instance_id ) :
region , ec2_url , aws_connect_params = get_aws_connection_info ( module , boto3 = True )
region , ec2_url , aws_connect_params = get_aws_connection_info ( module , boto3 = True )
as_group = asg_connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( asg_connection , group_name ) [ 0 ]
wait_timeout = module . params . get ( ' wait_timeout ' )
wait_timeout = module . params . get ( ' wait_timeout ' )
count = 1
count = 1
if as_group [ ' LoadBalancerNames ' ] and as_group [ ' HealthCheckType ' ] == ' ELB ' :
if as_group [ ' LoadBalancerNames ' ] and as_group [ ' HealthCheckType ' ] == ' ELB ' :
@ -485,15 +585,14 @@ def elb_dreg(asg_connection, module, group_name, instance_id):
return
return
for lb in as_group [ ' LoadBalancerNames ' ] :
for lb in as_group [ ' LoadBalancerNames ' ] :
elb_connection . deregister_instances_from_load_balancer ( LoadBalancerName = lb ,
deregister_lb_instances ( elb_connection , lb , instance_id )
Instances = [ dict ( InstanceId = instance_id ) ] )
log . debug ( " De-registering {0} from ELB {1} " . format ( instance_id , lb ) )
log . debug ( " De-registering {0} from ELB {1} " . format ( instance_id , lb ) )
wait_timeout = time . time ( ) + wait_timeout
wait_timeout = time . time ( ) + wait_timeout
while wait_timeout > time . time ( ) and count > 0 :
while wait_timeout > time . time ( ) and count > 0 :
count = 0
count = 0
for lb in as_group [ ' LoadBalancerNames ' ] :
for lb in as_group [ ' LoadBalancerNames ' ] :
lb_instances = elb_connection. describe_instance_health ( LoadBalancerName = lb )
lb_instances = describe_instance_health( elb_connection , lb , [ ] )
for i in lb_instances [ ' InstanceStates ' ] :
for i in lb_instances [ ' InstanceStates ' ] :
if i [ ' InstanceId ' ] == instance_id and i [ ' State ' ] == " InService " :
if i [ ' InstanceId ' ] == instance_id and i [ ' State ' ] == " InService " :
count + = 1
count + = 1
@ -507,7 +606,7 @@ def elb_dreg(asg_connection, module, group_name, instance_id):
def elb_healthy ( asg_connection , elb_connection , module , group_name ) :
def elb_healthy ( asg_connection , elb_connection , module , group_name ) :
healthy_instances = set ( )
healthy_instances = set ( )
as_group = asg_connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( asg_connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
# get healthy, inservice instances from ASG
# get healthy, inservice instances from ASG
instances = [ ]
instances = [ ]
@ -521,7 +620,7 @@ def elb_healthy(asg_connection, elb_connection, module, group_name):
# we catch a race condition that sometimes happens if the instance exists in the ASG
# we catch a race condition that sometimes happens if the instance exists in the ASG
# but has not yet show up in the ELB
# but has not yet show up in the ELB
try :
try :
lb_instances = elb_connection. describe_instance_health ( LoadBalancerName = lb , Instances = instances )
lb_instances = describe_instance_health( elb_connection , lb , instances )
except botocore . exceptions . ClientError as e :
except botocore . exceptions . ClientError as e :
if e . response [ ' Error ' ] [ ' Code ' ] == ' InvalidInstance ' :
if e . response [ ' Error ' ] [ ' Code ' ] == ' InvalidInstance ' :
return None
return None
@ -541,7 +640,7 @@ def elb_healthy(asg_connection, elb_connection, module, group_name):
def tg_healthy ( asg_connection , elbv2_connection , module , group_name ) :
def tg_healthy ( asg_connection , elbv2_connection , module , group_name ) :
healthy_instances = set ( )
healthy_instances = set ( )
as_group = asg_connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( asg_connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
# get healthy, inservice instances from ASG
# get healthy, inservice instances from ASG
instances = [ ]
instances = [ ]
@ -555,7 +654,7 @@ def tg_healthy(asg_connection, elbv2_connection, module, group_name):
# we catch a race condition that sometimes happens if the instance exists in the ASG
# we catch a race condition that sometimes happens if the instance exists in the ASG
# but has not yet show up in the ELB
# but has not yet show up in the ELB
try :
try :
tg_instances = elbv2_connection. describe_target_health ( TargetGroupArn = tg , Targets = instances )
tg_instances = describe_target_health( elbv2_connection , tg , instances )
except botocore . exceptions . ClientError as e :
except botocore . exceptions . ClientError as e :
if e . response [ ' Error ' ] [ ' Code ' ] == ' InvalidInstance ' :
if e . response [ ' Error ' ] [ ' Code ' ] == ' InvalidInstance ' :
return None
return None
@ -579,7 +678,7 @@ def wait_for_elb(asg_connection, module, group_name):
# if the health_check_type is ELB, we want to query the ELBs directly for instance
# if the health_check_type is ELB, we want to query the ELBs directly for instance
# status as to avoid health_check_grace period that is awarded to ASG instances
# status as to avoid health_check_grace period that is awarded to ASG instances
as_group = asg_connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( asg_connection , group_name ) [ 0 ]
if as_group . get ( ' LoadBalancerNames ' ) and as_group . get ( ' HealthCheckType ' ) == ' ELB ' :
if as_group . get ( ' LoadBalancerNames ' ) and as_group . get ( ' HealthCheckType ' ) == ' ELB ' :
log . debug ( " Waiting for ELB to consider instances healthy. " )
log . debug ( " Waiting for ELB to consider instances healthy. " )
@ -609,7 +708,7 @@ def wait_for_target_group(asg_connection, module, group_name):
# if the health_check_type is ELB, we want to query the ELBs directly for instance
# if the health_check_type is ELB, we want to query the ELBs directly for instance
# status as to avoid health_check_grace period that is awarded to ASG instances
# status as to avoid health_check_grace period that is awarded to ASG instances
as_group = asg_connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( asg_connection , group_name ) [ 0 ]
if as_group . get ( ' TargetGroupARNs ' ) and as_group . get ( ' HealthCheckType ' ) == ' ELB ' :
if as_group . get ( ' TargetGroupARNs ' ) and as_group . get ( ' HealthCheckType ' ) == ' ELB ' :
log . debug ( " Waiting for Target Group to consider instances healthy. " )
log . debug ( " Waiting for Target Group to consider instances healthy. " )
@ -647,10 +746,10 @@ def suspend_processes(ec2_connection, as_group, module):
resume_processes = list ( suspended_processes - suspend_processes )
resume_processes = list ( suspended_processes - suspend_processes )
if resume_processes :
if resume_processes :
ec2_connection. resume_processes ( AutoScalingGroupName = module . params . get ( ' name ' ) , ScalingProcesses = resume_processes )
resume_asg_processes( ec2_connection , module . params . get ( ' name ' ) , resume_processes )
if suspend_processes :
if suspend_processes :
ec2_connection. suspend_processes ( AutoScalingGroupName = module . params . get ( ' name ' ) , ScalingProcesses = list ( suspend_processes ) )
suspend_asg_processes( ec2_connection , module . params . get ( ' name ' ) , list ( suspend_processes ) )
return True
return True
@ -703,7 +802,7 @@ def create_autoscaling_group(connection, module):
availability_zones = module . params [ ' availability_zones ' ] = [ zone [ ' ZoneName ' ] for
availability_zones = module . params [ ' availability_zones ' ] = [ zone [ ' ZoneName ' ] for
zone in ec2_connection . describe_availability_zones ( ) [ ' AvailabilityZones ' ] ]
zone in ec2_connection . describe_availability_zones ( ) [ ' AvailabilityZones ' ] ]
enforce_required_arguments ( module )
enforce_required_arguments ( module )
launch_configs = connection. describe_launch_configurations ( LaunchConfigurationNames = [ launch_config_name ] )
launch_configs = describe_launch_configurations( connection , launch_config_name )
if len ( launch_configs [ ' LaunchConfigurations ' ] ) == 0 :
if len ( launch_configs [ ' LaunchConfigurations ' ] ) == 0 :
module . fail_json ( msg = " No launch config found with name %s " % launch_config_name )
module . fail_json ( msg = " No launch config found with name %s " % launch_config_name )
ag = dict (
ag = dict (
@ -729,9 +828,9 @@ def create_autoscaling_group(connection, module):
ag [ ' TargetGroupARNs ' ] = target_group_arns
ag [ ' TargetGroupARNs ' ] = target_group_arns
try :
try :
c onnection. create_auto_scaling_group ( * * ag )
c reate_asg( connection , * * ag )
all_ag = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ]
all_ag = describe_autoscaling_groups( connection , group_name )
if len ( all_ag ) == 0 :
if len ( all_ag ) == 0 :
module . fail_json ( msg = " No auto scaling group found with the name %s " % group_name )
module . fail_json ( msg = " No auto scaling group found with the name %s " % group_name )
as_group = all_ag [ 0 ]
as_group = all_ag [ 0 ]
@ -744,12 +843,8 @@ def create_autoscaling_group(connection, module):
if target_group_arns :
if target_group_arns :
wait_for_target_group ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
if notification_topic :
if notification_topic :
connection . put_notification_configuration (
put_notification_config ( connection , group_name , notification_topic , notification_types )
AutoScalingGroupName = group_name ,
as_group = describe_autoscaling_groups ( connection , group_name ) [ 0 ]
TopicARN = notification_topic ,
NotificationTypes = notification_types
)
as_group = connection . describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
asg_properties = get_properties ( as_group , module )
asg_properties = get_properties ( as_group , module )
changed = True
changed = True
return changed , asg_properties
return changed , asg_properties
@ -790,10 +885,7 @@ def create_autoscaling_group(connection, module):
if load_balancers and not as_group [ ' LoadBalancerNames ' ] :
if load_balancers and not as_group [ ' LoadBalancerNames ' ] :
changed = True
changed = True
try :
try :
connection . attach_load_balancers (
attach_load_balancers ( connection , group_name , load_balancers )
AutoScalingGroupName = group_name ,
LoadBalancerNames = load_balancers
)
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
module . fail_json ( msg = " Failed to update Autoscaling Group. " ,
module . fail_json ( msg = " Failed to update Autoscaling Group. " ,
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
@ -813,29 +905,20 @@ def create_autoscaling_group(connection, module):
elbs_to_detach = has_elbs . difference ( wanted_elbs )
elbs_to_detach = has_elbs . difference ( wanted_elbs )
if elbs_to_detach :
if elbs_to_detach :
changed = True
changed = True
connection . detach_load_balancers (
detach_load_balancers ( connection , group_name , list ( elbs_to_detach ) )
AutoScalingGroupName = group_name ,
LoadBalancerNames = list ( elbs_to_detach )
)
if wanted_elbs - has_elbs :
if wanted_elbs - has_elbs :
# if has contains less than wanted, then we need to add some
# if has contains less than wanted, then we need to add some
elbs_to_attach = wanted_elbs . difference ( has_elbs )
elbs_to_attach = wanted_elbs . difference ( has_elbs )
if elbs_to_attach :
if elbs_to_attach :
changed = True
changed = True
connection . attach_load_balancers (
attach_load_balancers ( connection , group_name , list ( elbs_to_attach ) )
AutoScalingGroupName = group_name ,
LoadBalancerNames = list ( elbs_to_attach )
)
# Handle target group attachments/detachments
# Handle target group attachments/detachments
# Attach target groups if they are specified but none currently exist
# Attach target groups if they are specified but none currently exist
if target_group_arns and not as_group [ ' TargetGroupARNs ' ] :
if target_group_arns and not as_group [ ' TargetGroupARNs ' ] :
changed = True
changed = True
try :
try :
connection . attach_load_balancer_target_groups (
attach_lb_target_groups ( connection , group_name , target_group_arns )
AutoScalingGroupName = group_name ,
TargetGroupARNs = target_group_arns
)
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
module . fail_json ( msg = " Failed to update Autoscaling Group. " ,
module . fail_json ( msg = " Failed to update Autoscaling Group. " ,
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
@ -850,19 +933,13 @@ def create_autoscaling_group(connection, module):
tgs_to_detach = has_tgs . difference ( wanted_tgs )
tgs_to_detach = has_tgs . difference ( wanted_tgs )
if tgs_to_detach :
if tgs_to_detach :
changed = True
changed = True
connection . detach_load_balancer_target_groups (
detach_lb_target_groups ( connection , group_name , tgs_to_detach )
AutoScalingGroupName = group_name ,
TargetGroupARNs = list ( tgs_to_detach )
)
if wanted_tgs . issuperset ( has_tgs ) :
if wanted_tgs . issuperset ( has_tgs ) :
# if has contains less than wanted, then we need to add some
# if has contains less than wanted, then we need to add some
tgs_to_attach = wanted_tgs . difference ( has_tgs )
tgs_to_attach = wanted_tgs . difference ( has_tgs )
if tgs_to_attach :
if tgs_to_attach :
changed = True
changed = True
connection . attach_load_balancer_target_groups (
attach_lb_target_groups ( connection , group_name , tgs_to_attach )
AutoScalingGroupName = group_name ,
TargetGroupARNs = list ( tgs_to_attach )
)
# check for attributes that aren't required for updating an existing ASG
# check for attributes that aren't required for updating an existing ASG
desired_capacity = desired_capacity or as_group [ ' DesiredCapacity ' ]
desired_capacity = desired_capacity or as_group [ ' DesiredCapacity ' ]
@ -870,7 +947,7 @@ def create_autoscaling_group(connection, module):
max_size = max_size or as_group [ ' MaxSize ' ]
max_size = max_size or as_group [ ' MaxSize ' ]
launch_config_name = launch_config_name or as_group [ ' LaunchConfigurationName ' ]
launch_config_name = launch_config_name or as_group [ ' LaunchConfigurationName ' ]
launch_configs = connection. describe_launch_configurations ( LaunchConfigurationNames = [ launch_config_name ] )
launch_configs = describe_launch_configurations( connection , launch_config_name )
if len ( launch_configs [ ' LaunchConfigurations ' ] ) == 0 :
if len ( launch_configs [ ' LaunchConfigurations ' ] ) == 0 :
module . fail_json ( msg = " No launch config found with name %s " % launch_config_name )
module . fail_json ( msg = " No launch config found with name %s " % launch_config_name )
ag = dict (
ag = dict (
@ -887,15 +964,11 @@ def create_autoscaling_group(connection, module):
ag [ ' AvailabilityZones ' ] = availability_zones
ag [ ' AvailabilityZones ' ] = availability_zones
if vpc_zone_identifier :
if vpc_zone_identifier :
ag [ ' VPCZoneIdentifier ' ] = vpc_zone_identifier
ag [ ' VPCZoneIdentifier ' ] = vpc_zone_identifier
connection. update_auto_scaling_group ( * * ag )
update_asg( connection , * * ag )
if notification_topic :
if notification_topic :
try :
try :
connection . put_notification_configuration (
put_notification_config ( connection , group_name , notification_topic , notification_types )
AutoScalingGroupName = group_name ,
TopicARN = notification_topic ,
NotificationTypes = notification_types
)
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
except ( botocore . exceptions . BotoCoreError , botocore . exceptions . ClientError ) as e :
module . fail_json ( msg = " Failed to update Autoscaling Group notifications. " ,
module . fail_json ( msg = " Failed to update Autoscaling Group notifications. " ,
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
exception = traceback . format_exc ( ) , * * camel_dict_to_snake_dict ( e . response ) )
@ -912,8 +985,7 @@ def create_autoscaling_group(connection, module):
wait_for_target_group ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
try :
try :
as_group = connection . describe_auto_scaling_groups (
as_group = describe_autoscaling_groups ( connection , group_name ) [ 0 ]
AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
asg_properties = get_properties ( as_group , module )
asg_properties = get_properties ( as_group , module )
if asg_properties != initial_asg_properties :
if asg_properties != initial_asg_properties :
changed = True
changed = True
@ -930,26 +1002,19 @@ def delete_autoscaling_group(connection, module):
wait_timeout = module . params . get ( ' wait_timeout ' )
wait_timeout = module . params . get ( ' wait_timeout ' )
if notification_topic :
if notification_topic :
connection . delete_notification_configuration (
del_notification_config ( connection , group_name , notification_topic )
AutoScalingGroupName = group_name ,
groups = describe_autoscaling_groups ( connection , group_name )
TopicARN = notification_topic
)
describe_response = connection . describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] )
groups = describe_response . get ( ' AutoScalingGroups ' )
if groups :
if groups :
if not wait_for_instances :
if not wait_for_instances :
connection. delete_auto_scaling_group ( AutoScalingGroupName = group_name , ForceD elete= True )
delete_asg ( connection , group_name , force_delete = True )
return True
return True
wait_timeout = time . time ( ) + wait_timeout
wait_timeout = time . time ( ) + wait_timeout
connection . update_auto_scaling_group (
updated_params = dict ( AutoScalingGroupName = group_name , MinSize = 0 , MaxSize = 0 , DesiredCapacity = 0 )
AutoScalingGroupName = group_name ,
update_asg ( connection , * * updated_params )
MinSize = 0 , MaxSize = 0 ,
DesiredCapacity = 0 )
instances = True
instances = True
while instances and wait_for_instances and wait_timeout > = time . time ( ) :
while instances and wait_for_instances and wait_timeout > = time . time ( ) :
tmp_groups = connection . describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) . get (
tmp_groups = describe_autoscaling_groups ( connection , group_name )
' AutoScalingGroups ' )
if tmp_groups :
if tmp_groups :
tmp_group = tmp_groups [ 0 ]
tmp_group = tmp_groups [ 0 ]
if not tmp_group . get ( ' Instances ' ) :
if not tmp_group . get ( ' Instances ' ) :
@ -960,8 +1025,8 @@ def delete_autoscaling_group(connection, module):
# waiting took too long
# waiting took too long
module . fail_json ( msg = " Waited too long for old instances to terminate. %s " % time . asctime ( ) )
module . fail_json ( msg = " Waited too long for old instances to terminate. %s " % time . asctime ( ) )
connection. delete_auto_scaling_group ( AutoScalingGroupName = group_nam e)
delete_asg( connection , group_name , force_delete = Fals e)
while len ( connection . describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) . get ( ' AutoScalingGroups ' ) ) :
while describe_autoscaling_groups ( connection , group_name ) :
time . sleep ( 5 )
time . sleep ( 5 )
return True
return True
@ -982,7 +1047,7 @@ def update_size(connection, group, max_size, min_size, dc):
updated_group [ ' MinSize ' ] = min_size
updated_group [ ' MinSize ' ] = min_size
updated_group [ ' MaxSize ' ] = max_size
updated_group [ ' MaxSize ' ] = max_size
updated_group [ ' DesiredCapacity ' ] = dc
updated_group [ ' DesiredCapacity ' ] = dc
connection. update_auto_scaling_group ( * * updated_group )
update_asg( connection , * * updated_group )
def replace ( connection , module ) :
def replace ( connection , module ) :
@ -995,7 +1060,7 @@ def replace(connection, module):
lc_check = module . params . get ( ' lc_check ' )
lc_check = module . params . get ( ' lc_check ' )
replace_instances = module . params . get ( ' replace_instances ' )
replace_instances = module . params . get ( ' replace_instances ' )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
wait_for_new_inst ( module , connection , group_name , wait_timeout , as_group [ ' MinSize ' ] , ' viable_instances ' )
wait_for_new_inst ( module , connection , group_name , wait_timeout , as_group [ ' MinSize ' ] , ' viable_instances ' )
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
instances = props [ ' instances ' ]
instances = props [ ' instances ' ]
@ -1010,7 +1075,7 @@ def replace(connection, module):
if num_new_inst_needed == 0 and old_instances :
if num_new_inst_needed == 0 and old_instances :
log . debug ( " No new instances needed, but old instances are present. Removing old instances " )
log . debug ( " No new instances needed, but old instances are present. Removing old instances " )
terminate_batch ( connection , module , old_instances , instances , True )
terminate_batch ( connection , module , old_instances , instances , True )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
changed = True
changed = True
return ( changed , props )
return ( changed , props )
@ -1034,12 +1099,12 @@ def replace(connection, module):
# set temporary settings and wait for them to be reached
# set temporary settings and wait for them to be reached
# This should get overwritten if the number of instances left is less than the batch size.
# This should get overwritten if the number of instances left is less than the batch size.
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
update_size ( connection , as_group , max_size + batch_size , min_size + batch_size , desired_capacity + batch_size )
update_size ( connection , as_group , max_size + batch_size , min_size + batch_size , desired_capacity + batch_size )
wait_for_new_inst ( module , connection , group_name , wait_timeout , as_group [ ' MinSize ' ] , ' viable_instances ' )
wait_for_new_inst ( module , connection , group_name , wait_timeout , as_group [ ' MinSize ' ] , ' viable_instances ' )
wait_for_elb ( connection , module , group_name )
wait_for_elb ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
instances = props [ ' instances ' ]
instances = props [ ' instances ' ]
if replace_instances :
if replace_instances :
@ -1052,12 +1117,12 @@ def replace(connection, module):
wait_for_new_inst ( module , connection , group_name , wait_timeout , desired_size , ' viable_instances ' )
wait_for_new_inst ( module , connection , group_name , wait_timeout , desired_size , ' viable_instances ' )
wait_for_elb ( connection , module , group_name )
wait_for_elb ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
wait_for_target_group ( connection , module , group_name )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
if break_early :
if break_early :
log . debug ( " breaking loop " )
log . debug ( " breaking loop " )
break
break
update_size ( connection , as_group , max_size , min_size , desired_capacity )
update_size ( connection , as_group , max_size , min_size , desired_capacity )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
asg_properties = get_properties ( as_group , module )
asg_properties = get_properties ( as_group , module )
log . debug ( " Rolling update complete. " )
log . debug ( " Rolling update complete. " )
changed = True
changed = True
@ -1115,7 +1180,7 @@ def terminate_batch(connection, module, replace_instances, initial_instances, le
decrement_capacity = False
decrement_capacity = False
break_loop = False
break_loop = False
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
desired_size = as_group [ ' MinSize ' ]
desired_size = as_group [ ' MinSize ' ]
@ -1134,8 +1199,8 @@ def terminate_batch(connection, module, replace_instances, initial_instances, le
if num_new_inst_needed == 0 :
if num_new_inst_needed == 0 :
decrement_capacity = True
decrement_capacity = True
if as_group [ ' MinSize ' ] != min_size :
if as_group [ ' MinSize ' ] != min_size :
connection. update_auto_scaling_group ( AutoScalingGroupName = as_group [ ' AutoScalingGroupName ' ] ,
updated_params = dict ( AutoScalingGroupName = as_group [ ' AutoScalingGroupName ' ] , MinSize = min_size )
MinSize = min_size )
update_asg ( connection , * * updated_params )
log . debug ( " Updating minimum size back to original of {0} " . format ( min_size ) )
log . debug ( " Updating minimum size back to original of {0} " . format ( min_size ) )
# if are some leftover old instances, but we are already at capacity with new ones
# if are some leftover old instances, but we are already at capacity with new ones
# we don't want to decrement capacity
# we don't want to decrement capacity
@ -1157,8 +1222,7 @@ def terminate_batch(connection, module, replace_instances, initial_instances, le
for instance_id in instances_to_terminate :
for instance_id in instances_to_terminate :
elb_dreg ( connection , module , group_name , instance_id )
elb_dreg ( connection , module , group_name , instance_id )
log . debug ( " terminating instance: {0} " . format ( instance_id ) )
log . debug ( " terminating instance: {0} " . format ( instance_id ) )
connection . terminate_instance_in_auto_scaling_group ( InstanceId = instance_id ,
terminate_asg_instance ( connection , instance_id , decrement_capacity )
ShouldDecrementDesiredCapacity = decrement_capacity )
# we wait to make sure the machines we marked as Unhealthy are
# we wait to make sure the machines we marked as Unhealthy are
# no longer in the list
# no longer in the list
@ -1169,14 +1233,14 @@ def terminate_batch(connection, module, replace_instances, initial_instances, le
def wait_for_term_inst ( connection , module , term_instances ) :
def wait_for_term_inst ( connection , module , term_instances ) :
wait_timeout = module . params . get ( ' wait_timeout ' )
wait_timeout = module . params . get ( ' wait_timeout ' )
group_name = module . params . get ( ' name ' )
group_name = module . params . get ( ' name ' )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
count = 1
count = 1
wait_timeout = time . time ( ) + wait_timeout
wait_timeout = time . time ( ) + wait_timeout
while wait_timeout > time . time ( ) and count > 0 :
while wait_timeout > time . time ( ) and count > 0 :
log . debug ( " waiting for instances to terminate " )
log . debug ( " waiting for instances to terminate " )
count = 0
count = 0
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
instance_facts = props [ ' instance_facts ' ]
instance_facts = props [ ' instance_facts ' ]
instances = ( i for i in instance_facts if i in term_instances )
instances = ( i for i in instance_facts if i in term_instances )
@ -1196,7 +1260,7 @@ def wait_for_term_inst(connection, module, term_instances):
def wait_for_new_inst ( module , connection , group_name , wait_timeout , desired_size , prop ) :
def wait_for_new_inst ( module , connection , group_name , wait_timeout , desired_size , prop ) :
# make sure we have the latest stats after that last loop.
# make sure we have the latest stats after that last loop.
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
log . debug ( " Waiting for {0} = {1} , currently {2} " . format ( prop , desired_size , props [ prop ] ) )
log . debug ( " Waiting for {0} = {1} , currently {2} " . format ( prop , desired_size , props [ prop ] ) )
# now we make sure that we have enough instances in a viable state
# now we make sure that we have enough instances in a viable state
@ -1204,7 +1268,7 @@ def wait_for_new_inst(module, connection, group_name, wait_timeout, desired_size
while wait_timeout > time . time ( ) and desired_size > props [ prop ] :
while wait_timeout > time . time ( ) and desired_size > props [ prop ] :
log . debug ( " Waiting for {0} = {1} , currently {2} " . format ( prop , desired_size , props [ prop ] ) )
log . debug ( " Waiting for {0} = {1} , currently {2} " . format ( prop , desired_size , props [ prop ] ) )
time . sleep ( 10 )
time . sleep ( 10 )
as_group = connection. describe_auto_scaling_groups ( AutoScalingGroupNames = [ group_name ] ) [ ' AutoScalingGroups ' ] [ 0 ]
as_group = describe_autoscaling_groups( connection , group_name ) [ 0 ]
props = get_properties ( as_group , module )
props = get_properties ( as_group , module )
if wait_timeout < = time . time ( ) :
if wait_timeout < = time . time ( ) :
# waiting took too long
# waiting took too long