| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | import boto3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from moto import mock_autoscaling, mock_elb, mock_ec2 | 
					
						
							|  |  |  | from .utils import setup_networking | 
					
						
							|  |  |  | from tests import EXAMPLE_AMI_ID | 
					
						
							|  |  |  | from unittest import TestCase | 
					
						
							|  |  |  | from uuid import uuid4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_autoscaling | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_elb | 
					
						
							|  |  |  | class TestAutoScalingELB(TestCase): | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.mocked_networking = setup_networking() | 
					
						
							|  |  |  |         self.instance_count = 2 | 
					
						
							|  |  |  |         self.elb_client = boto3.client("elb", region_name="us-east-1") | 
					
						
							|  |  |  |         self.as_client = boto3.client("autoscaling", region_name="us-east-1") | 
					
						
							|  |  |  |         self.lb_name = str(uuid4()) | 
					
						
							|  |  |  |         self.asg_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lc_name = str(uuid4()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.elb_client.create_load_balancer( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name, | 
					
						
							|  |  |  |             Listeners=[ | 
					
						
							|  |  |  |                 {"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             AvailabilityZones=["us-east-1a", "us-east-1b"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.as_client.create_launch_configuration( | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.medium", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_describe_load_balancers(self): | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name], | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=self.instance_count, | 
					
						
							|  |  |  |             DesiredCapacity=self.instance_count, | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         assert response["ResponseMetadata"]["RequestId"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancers"])) == 1 | 
					
						
							|  |  |  |         assert response["LoadBalancers"][0]["LoadBalancerName"] == self.lb_name | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_create_elb_and_autoscaling_group_no_relationship(self): | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=self.instance_count, | 
					
						
							|  |  |  |             DesiredCapacity=self.instance_count, | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # autoscaling group and elb should have no relationship | 
					
						
							|  |  |  |         response = self.as_client.describe_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancers"])) == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_attach_load_balancer(self): | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=self.instance_count, | 
					
						
							|  |  |  |             DesiredCapacity=self.instance_count, | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.attach_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert ( | 
					
						
							|  |  |  |             len(list(response["LoadBalancerDescriptions"][0]["Instances"])) | 
					
						
							|  |  |  |             == self.instance_count | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["AutoScalingGroups"][0]["LoadBalancerNames"])) == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_detach_load_balancer(self): | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name], | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=self.instance_count, | 
					
						
							|  |  |  |             DesiredCapacity=self.instance_count, | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.detach_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancers"])) == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_create_autoscaling_group_within_elb(self): | 
					
						
							|  |  |  |         # we attach a couple of machines to the load balancer | 
					
						
							|  |  |  |         # that are not managed by the auto scaling group | 
					
						
							|  |  |  |         INSTANCE_COUNT_START = 3 | 
					
						
							|  |  |  |         INSTANCE_COUNT_GROUP = 2 | 
					
						
							|  |  |  |         ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |         instances = ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t1.micro", | 
					
						
							|  |  |  |             MaxCount=INSTANCE_COUNT_START, | 
					
						
							|  |  |  |             MinCount=INSTANCE_COUNT_START, | 
					
						
							|  |  |  |             SubnetId=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         instances_ids = [_.id for _ in instances] | 
					
						
							|  |  |  |         self.elb_client.register_instances_with_load_balancer( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name, | 
					
						
							|  |  |  |             Instances=[{"InstanceId": id} for id in instances_ids], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.create_launch_configuration( | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.medium", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             AvailabilityZones=["us-east-1a", "us-east-1b"], | 
					
						
							|  |  |  |             DefaultCooldown=60, | 
					
						
							|  |  |  |             DesiredCapacity=INSTANCE_COUNT_GROUP, | 
					
						
							|  |  |  |             HealthCheckGracePeriod=100, | 
					
						
							|  |  |  |             HealthCheckType="EC2", | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name], | 
					
						
							|  |  |  |             MinSize=INSTANCE_COUNT_GROUP, | 
					
						
							|  |  |  |             MaxSize=INSTANCE_COUNT_GROUP, | 
					
						
							|  |  |  |             PlacementGroup="test_placement", | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "ResourceType": "group", | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             TerminationPolicies=["OldestInstance", "NewestInstance"], | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |             VPCZoneIdentifier=f"{self.mocked_networking['subnet1']},{self.mocked_networking['subnet2']}", | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.put_scheduled_update_group_action( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             ScheduledActionName="my-scheduled-action", | 
					
						
							|  |  |  |             StartTime="2022-07-01T00:00:00Z", | 
					
						
							|  |  |  |             EndTime="2022-09-01T00:00:00Z", | 
					
						
							|  |  |  |             Recurrence="* * * * *", | 
					
						
							|  |  |  |             MinSize=5, | 
					
						
							|  |  |  |             MaxSize=12, | 
					
						
							|  |  |  |             DesiredCapacity=9, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         resp = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         group = resp["AutoScalingGroups"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert group["AutoScalingGroupName"] == self.asg_name | 
					
						
							|  |  |  |         assert set(group["AvailabilityZones"]) == set(["us-east-1a", "us-east-1b"]) | 
					
						
							|  |  |  |         assert group["DesiredCapacity"] == 2 | 
					
						
							|  |  |  |         assert group["MaxSize"] == INSTANCE_COUNT_GROUP | 
					
						
							|  |  |  |         assert group["MinSize"] == INSTANCE_COUNT_GROUP | 
					
						
							|  |  |  |         assert len(group["Instances"]) == INSTANCE_COUNT_GROUP | 
					
						
							|  |  |  |         assert ( | 
					
						
							|  |  |  |             group["VPCZoneIdentifier"] | 
					
						
							|  |  |  |             == f"{self.mocked_networking['subnet1']},{self.mocked_networking['subnet2']}" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         assert group["LaunchConfigurationName"] == self.lc_name | 
					
						
							|  |  |  |         assert group["DefaultCooldown"] == 60 | 
					
						
							|  |  |  |         assert group["HealthCheckGracePeriod"] == 100 | 
					
						
							|  |  |  |         assert group["HealthCheckType"] == "EC2" | 
					
						
							|  |  |  |         assert group["LoadBalancerNames"] == [self.lb_name] | 
					
						
							|  |  |  |         assert group["PlacementGroup"] == "test_placement" | 
					
						
							|  |  |  |         assert list(group["TerminationPolicies"]) == [ | 
					
						
							|  |  |  |             "OldestInstance", | 
					
						
							|  |  |  |             "NewestInstance", | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         assert len(list(group["Tags"])) == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         tag = group["Tags"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert tag["ResourceId"] == self.asg_name | 
					
						
							|  |  |  |         assert tag["Key"] == "test_key" | 
					
						
							|  |  |  |         assert tag["Value"] == "test_value" | 
					
						
							|  |  |  |         assert tag["PropagateAtLaunch"] is True | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         instances_attached = self.elb_client.describe_instance_health( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name | 
					
						
							|  |  |  |         )["InstanceStates"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(instances_attached) == INSTANCE_COUNT_START + INSTANCE_COUNT_GROUP | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         attached_ids = [i["InstanceId"] for i in instances_attached] | 
					
						
							|  |  |  |         for ec2_instance_id in instances_ids: | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |             assert ec2_instance_id in attached_ids | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         scheduled_actions = self.as_client.describe_scheduled_actions( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         scheduled_action_1 = scheduled_actions["ScheduledUpdateGroupActions"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert scheduled_action_1["AutoScalingGroupName"] == self.asg_name | 
					
						
							|  |  |  |         assert scheduled_action_1["DesiredCapacity"] == 9 | 
					
						
							|  |  |  |         assert scheduled_action_1["MaxSize"] == 12 | 
					
						
							|  |  |  |         assert scheduled_action_1["MinSize"] == 5 | 
					
						
							|  |  |  |         assert "StartTime" in scheduled_action_1 | 
					
						
							|  |  |  |         assert "EndTime" in scheduled_action_1 | 
					
						
							|  |  |  |         assert scheduled_action_1["Recurrence"] == "* * * * *" | 
					
						
							|  |  |  |         assert scheduled_action_1["ScheduledActionName"] == "my-scheduled-action" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_autoscaling | 
					
						
							|  |  |  | @mock_elb | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | class TestAutoScalingInstances(TestCase): | 
					
						
							|  |  |  |     def setUp(self) -> None: | 
					
						
							|  |  |  |         self.mocked_networking = setup_networking() | 
					
						
							|  |  |  |         self.as_client = boto3.client("autoscaling", region_name="us-east-1") | 
					
						
							|  |  |  |         self.elb_client = boto3.client("elb", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.asg_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lb_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lc_name = str(uuid4()) | 
					
						
							|  |  |  |         self.as_client.create_launch_configuration( | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.medium", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=2, | 
					
						
							|  |  |  |             DesiredCapacity=2, | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.elb_client.create_load_balancer( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name, | 
					
						
							|  |  |  |             Listeners=[ | 
					
						
							|  |  |  |                 {"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             AvailabilityZones=["us-east-1a", "us-east-1b"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.attach_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_detach_one_instance_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_detach = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         instance_to_keep = response["AutoScalingGroups"][0]["Instances"][1][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.detach_instances( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 1 | 
					
						
							|  |  |  |         assert instance_to_detach not in [ | 
					
						
							|  |  |  |             x["InstanceId"] for x in response["AutoScalingGroups"][0]["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # test to ensure tag has been removed | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_detach]) | 
					
						
							|  |  |  |         tags = response["Reservations"][0]["Instances"][0]["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(tags) == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # test to ensure tag is present on other instance | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_keep]) | 
					
						
							|  |  |  |         tags = response["Reservations"][0]["Instances"][0]["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(tags) == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 1 | 
					
						
							|  |  |  |         assert instance_to_detach not in [ | 
					
						
							|  |  |  |             x["InstanceId"] | 
					
						
							|  |  |  |             for x in response["LoadBalancerDescriptions"][0]["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_detach_one_instance(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_detach = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         instance_to_keep = response["AutoScalingGroups"][0]["Instances"][1][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.detach_instances( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         # test to ensure instance was replaced | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_detach]) | 
					
						
							|  |  |  |         tags = response["Reservations"][0]["Instances"][0]["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(tags) == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_keep]) | 
					
						
							|  |  |  |         tags = response["Reservations"][0]["Instances"][0]["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(tags) == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 2 | 
					
						
							|  |  |  |         assert instance_to_detach not in [ | 
					
						
							|  |  |  |             x["InstanceId"] | 
					
						
							|  |  |  |             for x in response["LoadBalancerDescriptions"][0]["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_one_instance_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 2 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # test to ensure tag has been retained (standby instance is still part of the ASG) | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_standby]) | 
					
						
							|  |  |  |         for reservation in response["Reservations"]: | 
					
						
							|  |  |  |             for instance in reservation["Instances"]: | 
					
						
							|  |  |  |                 tags = instance["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |                 assert len(tags) == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["LoadBalancerDescriptions"][0]["Instances"]) == 1 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_one_instance(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # test to ensure tag has been retained (standby instance is still part of the ASG) | 
					
						
							|  |  |  |         response = ec2_client.describe_instances(InstanceIds=[instance_to_standby]) | 
					
						
							|  |  |  |         for reservation in response["Reservations"]: | 
					
						
							|  |  |  |             for instance in reservation["Instances"]: | 
					
						
							|  |  |  |                 tags = instance["Tags"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |                 assert len(tags) == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["LoadBalancerDescriptions"][0]["Instances"]) == 2 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_elb_update(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["LoadBalancerDescriptions"][0]["Instances"]) == 2 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_terminate_instance_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby_terminate = response["AutoScalingGroups"][0]["Instances"][ | 
					
						
							|  |  |  |             0 | 
					
						
							|  |  |  |         ]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.terminate_instance_in_auto_scaling_group( | 
					
						
							|  |  |  |             InstanceId=instance_to_standby_terminate, | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # AWS still decrements desired capacity ASG if requested, even if the terminated instance is in standby | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 1 | 
					
						
							|  |  |  |         assert ( | 
					
						
							|  |  |  |             response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  |             != instance_to_standby_terminate | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = ec2_client.describe_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert ( | 
					
						
							|  |  |  |             response["Reservations"][0]["Instances"][0]["State"]["Name"] == "terminated" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 1 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby_terminate | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_terminate_instance_no_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby_terminate = response["AutoScalingGroups"][0]["Instances"][ | 
					
						
							|  |  |  |             0 | 
					
						
							|  |  |  |         ]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.terminate_instance_in_auto_scaling_group( | 
					
						
							|  |  |  |             InstanceId=instance_to_standby_terminate, | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         group = response["AutoScalingGroups"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(group["Instances"]) == 2 | 
					
						
							|  |  |  |         assert instance_to_standby_terminate not in [ | 
					
						
							|  |  |  |             x["InstanceId"] for x in group["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         assert group["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = ec2_client.describe_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_terminate] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert ( | 
					
						
							|  |  |  |             response["Reservations"][0]["Instances"][0]["State"]["Name"] == "terminated" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["LoadBalancerDescriptions"][0]["Instances"]) == 2 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby_terminate | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_detach_instance_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby_detach = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.detach_instances( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # AWS still decrements desired capacity ASG if requested, even if the detached instance was in standby | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         group = self.as_client.describe_auto_scaling_groups( | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         )["AutoScalingGroups"][0] | 
					
						
							|  |  |  |         assert len(group["Instances"]) == 1 | 
					
						
							|  |  |  |         assert group["Instances"][0]["InstanceId"] != instance_to_standby_detach | 
					
						
							|  |  |  |         assert group["DesiredCapacity"] == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         instance = ec2_client.describe_instances( | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |             InstanceIds=[instance_to_standby_detach] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         )["Reservations"][0]["Instances"][0] | 
					
						
							|  |  |  |         assert instance["State"]["Name"] == "running" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["LoadBalancerDescriptions"][0]["Instances"]) == 1 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby_detach | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_detach_instance_no_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby_detach = response["AutoScalingGroups"][0]["Instances"][0][ | 
					
						
							|  |  |  |             "InstanceId" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.detach_instances( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_detach], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         group = response["AutoScalingGroups"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(group["Instances"]) == 2 | 
					
						
							|  |  |  |         assert instance_to_standby_detach not in [ | 
					
						
							|  |  |  |             x["InstanceId"] for x in group["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         assert group["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         instance = ec2_client.describe_instances( | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |             InstanceIds=[instance_to_standby_detach] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         )["Reservations"][0]["Instances"][0] | 
					
						
							|  |  |  |         assert instance["State"]["Name"] == "running" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 2 | 
					
						
							|  |  |  |         for x in response["LoadBalancerDescriptions"][0]["Instances"]: | 
					
						
							|  |  |  |             assert x["InstanceId"] not in instance_to_standby_detach | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_standby_exit_standby(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instance_to_standby_exit_standby = response["AutoScalingGroups"][0][ | 
					
						
							|  |  |  |             "Instances" | 
					
						
							|  |  |  |         ][0]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.enter_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_exit_standby], | 
					
						
							|  |  |  |             ShouldDecrementDesiredCapacity=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(response["AutoScalingGroups"][0]["Instances"]) == 3 | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 2 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_instances( | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_exit_standby] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingInstances"][0]["LifecycleState"] == "Standby" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.exit_standby( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             InstanceIds=[instance_to_standby_exit_standby], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         group = response["AutoScalingGroups"][0] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(group["Instances"]) == 3 | 
					
						
							|  |  |  |         assert instance_to_standby_exit_standby in [ | 
					
						
							|  |  |  |             x["InstanceId"] for x in group["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         assert group["DesiredCapacity"] == 3 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         instance = ec2_client.describe_instances( | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |             InstanceIds=[instance_to_standby_exit_standby] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         )["Reservations"][0]["Instances"][0] | 
					
						
							|  |  |  |         assert instance["State"]["Name"] == "running" | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 3 | 
					
						
							|  |  |  |         assert instance_to_standby_exit_standby in [ | 
					
						
							|  |  |  |             x["InstanceId"] | 
					
						
							|  |  |  |             for x in response["LoadBalancerDescriptions"][0]["Instances"] | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_autoscaling | 
					
						
							|  |  |  | @mock_elb | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | class TestAutoScalingInstancesProtected(TestCase): | 
					
						
							|  |  |  |     def setUp(self) -> None: | 
					
						
							|  |  |  |         self.mocked_networking = setup_networking() | 
					
						
							|  |  |  |         self.as_client = boto3.client("autoscaling", region_name="us-east-1") | 
					
						
							|  |  |  |         self.elb_client = boto3.client("elb", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.asg_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lb_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lc_name = str(uuid4()) | 
					
						
							|  |  |  |         self.as_client.create_launch_configuration( | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.medium", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             MaxSize=4, | 
					
						
							|  |  |  |             DesiredCapacity=2, | 
					
						
							|  |  |  |             Tags=[ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "ResourceId": self.asg_name, | 
					
						
							|  |  |  |                     "Key": "test_key", | 
					
						
							|  |  |  |                     "Value": "test_value", | 
					
						
							|  |  |  |                     "PropagateAtLaunch": True, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |             NewInstancesProtectedFromScaleIn=True, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.elb_client.create_load_balancer( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name, | 
					
						
							|  |  |  |             Listeners=[ | 
					
						
							|  |  |  |                 {"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             AvailabilityZones=["us-east-1a", "us-east-1b"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.attach_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_attach_one_instance(self): | 
					
						
							|  |  |  |         ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |         instances_to_add = [ | 
					
						
							|  |  |  |             x.id | 
					
						
							|  |  |  |             for x in ec2.create_instances( | 
					
						
							|  |  |  |                 ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1 | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.attach_instances( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, InstanceIds=instances_to_add | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         instances = response["AutoScalingGroups"][0]["Instances"] | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(instances) == 3 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  |         for instance in instances: | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |             assert instance["ProtectedFromScaleIn"] is True | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 3 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_autoscaling | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_elb | 
					
						
							|  |  |  | class TestAutoScalingTerminateInstances(TestCase): | 
					
						
							|  |  |  |     def setUp(self) -> None: | 
					
						
							|  |  |  |         self.mocked_networking = setup_networking() | 
					
						
							|  |  |  |         self.as_client = boto3.client("autoscaling", region_name="us-east-1") | 
					
						
							|  |  |  |         self.elb_client = boto3.client("elb", region_name="us-east-1") | 
					
						
							|  |  |  |         self.lb_name = str(uuid4()) | 
					
						
							|  |  |  |         self.lc_name = str(uuid4()) | 
					
						
							|  |  |  |         self.asg_name = str(uuid4()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.as_client.create_launch_configuration( | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.medium", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.as_client.create_auto_scaling_group( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, | 
					
						
							|  |  |  |             LaunchConfigurationName=self.lc_name, | 
					
						
							|  |  |  |             MinSize=0, | 
					
						
							|  |  |  |             DesiredCapacity=1, | 
					
						
							|  |  |  |             MaxSize=2, | 
					
						
							|  |  |  |             VPCZoneIdentifier=self.mocked_networking["subnet1"], | 
					
						
							|  |  |  |             NewInstancesProtectedFromScaleIn=False, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.elb_client.create_load_balancer( | 
					
						
							|  |  |  |             LoadBalancerName=self.lb_name, | 
					
						
							|  |  |  |             Listeners=[ | 
					
						
							|  |  |  |                 {"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             AvailabilityZones=["us-east-1a", "us-east-1b"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.as_client.attach_load_balancers( | 
					
						
							|  |  |  |             AutoScalingGroupName=self.asg_name, LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_terminate_instance_in_auto_scaling_group_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         original_instance_id = next( | 
					
						
							|  |  |  |             instance["InstanceId"] | 
					
						
							|  |  |  |             for instance in response["AutoScalingGroups"][0]["Instances"] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.as_client.terminate_instance_in_auto_scaling_group( | 
					
						
							|  |  |  |             InstanceId=original_instance_id, ShouldDecrementDesiredCapacity=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert response["AutoScalingGroups"][0]["Instances"] == [] | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 0 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_terminate_instance_in_auto_scaling_group_no_decrement(self): | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         original_instance_id = next( | 
					
						
							|  |  |  |             instance["InstanceId"] | 
					
						
							|  |  |  |             for instance in response["AutoScalingGroups"][0]["Instances"] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.as_client.terminate_instance_in_auto_scaling_group( | 
					
						
							|  |  |  |             InstanceId=original_instance_id, ShouldDecrementDesiredCapacity=False | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         response = self.as_client.describe_auto_scaling_groups( | 
					
						
							|  |  |  |             AutoScalingGroupNames=[self.asg_name] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         replaced_instance_id = next( | 
					
						
							|  |  |  |             instance["InstanceId"] | 
					
						
							|  |  |  |             for instance in response["AutoScalingGroups"][0]["Instances"] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert replaced_instance_id != original_instance_id | 
					
						
							|  |  |  |         assert response["AutoScalingGroups"][0]["DesiredCapacity"] == 1 | 
					
						
							| 
									
										
										
										
											2022-08-28 14:41:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         response = self.elb_client.describe_load_balancers( | 
					
						
							|  |  |  |             LoadBalancerNames=[self.lb_name] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-06-09 11:16:59 +00:00
										 |  |  |         assert len(list(response["LoadBalancerDescriptions"][0]["Instances"])) == 1 | 
					
						
							|  |  |  |         assert original_instance_id not in [ | 
					
						
							|  |  |  |             x["InstanceId"] | 
					
						
							|  |  |  |             for x in response["LoadBalancerDescriptions"][0]["Instances"] | 
					
						
							|  |  |  |         ] |