Add support for Launch Templates in Auto Scaling Groups (#3236)
* Add support for Launch Templates in Auto Scaling Groups * Use named parameters, simplify parameter validation
This commit is contained in:
parent
2a27e457bf
commit
55b02c6ee9
8 changed files with 774 additions and 42 deletions
|
|
@ -17,6 +17,7 @@ from moto import (
|
|||
mock_elb,
|
||||
mock_autoscaling_deprecated,
|
||||
mock_ec2,
|
||||
mock_cloudformation,
|
||||
)
|
||||
from tests.helpers import requires_boto_gte
|
||||
|
||||
|
|
@ -164,7 +165,7 @@ def test_list_many_autoscaling_groups():
|
|||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_list_many_autoscaling_groups():
|
||||
def test_propogate_tags():
|
||||
mocked_networking = setup_networking()
|
||||
conn = boto3.client("autoscaling", region_name="us-east-1")
|
||||
conn.create_launch_configuration(LaunchConfigurationName="TestLC")
|
||||
|
|
@ -692,7 +693,7 @@ def test_detach_load_balancer():
|
|||
def test_create_autoscaling_group_boto3():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
_ = client.create_launch_configuration(
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
)
|
||||
response = client.create_auto_scaling_group(
|
||||
|
|
@ -798,13 +799,171 @@ def test_create_autoscaling_group_from_invalid_instance_id():
|
|||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_describe_autoscaling_groups_boto3():
|
||||
@mock_ec2
|
||||
def test_create_autoscaling_group_from_template():
|
||||
mocked_networking = setup_networking()
|
||||
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
response = client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"Version": str(template["LatestVersionNumber"]),
|
||||
},
|
||||
MinSize=1,
|
||||
MaxSize=3,
|
||||
DesiredCapacity=2,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_create_autoscaling_group_no_template_ref():
|
||||
mocked_networking = setup_networking()
|
||||
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={"Version": str(template["LatestVersionNumber"])},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Code"].should.equal("ValidationError")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"Valid requests must contain either launchTemplateId or LaunchTemplateName"
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_create_autoscaling_group_multiple_template_ref():
|
||||
mocked_networking = setup_networking()
|
||||
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"LaunchTemplateName": template["LaunchTemplateName"],
|
||||
"Version": str(template["LatestVersionNumber"]),
|
||||
},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Code"].should.equal("ValidationError")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"Valid requests must contain either launchTemplateId or LaunchTemplateName"
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_create_autoscaling_group_boto3_no_launch_configuration():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
_ = client.create_launch_configuration(
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Code"].should.equal("ValidationError")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"Valid requests must contain either LaunchTemplate, LaunchConfigurationName, "
|
||||
"InstanceId or MixedInstancesPolicy parameter."
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_create_autoscaling_group_boto3_multiple_launch_configurations():
|
||||
mocked_networking = setup_networking()
|
||||
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
)
|
||||
_ = client.create_auto_scaling_group(
|
||||
|
||||
with assert_raises(ClientError) as ex:
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
LaunchTemplate={
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"Version": str(template["LatestVersionNumber"]),
|
||||
},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.exception.response["Error"]["Code"].should.equal("ValidationError")
|
||||
ex.exception.response["Error"]["Message"].should.equal(
|
||||
"Valid requests must contain either LaunchTemplate, LaunchConfigurationName, "
|
||||
"InstanceId or MixedInstancesPolicy parameter."
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_describe_autoscaling_groups_boto3_launch_config():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration", InstanceType="t2.micro",
|
||||
)
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
|
|
@ -818,22 +977,72 @@ def test_describe_autoscaling_groups_boto3():
|
|||
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group["AutoScalingGroupName"].should.equal("test_asg")
|
||||
group["LaunchConfigurationName"].should.equal("test_launch_configuration")
|
||||
group.should_not.have.key("LaunchTemplate")
|
||||
group["AvailabilityZones"].should.equal(["us-east-1a"])
|
||||
group["VPCZoneIdentifier"].should.equal(mocked_networking["subnet1"])
|
||||
group["NewInstancesProtectedFromScaleIn"].should.equal(True)
|
||||
for instance in group["Instances"]:
|
||||
instance["LaunchConfigurationName"].should.equal("test_launch_configuration")
|
||||
instance.should_not.have.key("LaunchTemplate")
|
||||
instance["AvailabilityZone"].should.equal("us-east-1a")
|
||||
instance["ProtectedFromScaleIn"].should.equal(True)
|
||||
instance["InstanceType"].should.equal("t2.micro")
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_describe_autoscaling_instances_boto3():
|
||||
@mock_ec2
|
||||
def test_describe_autoscaling_groups_boto3_launch_template():
|
||||
mocked_networking = setup_networking()
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={"LaunchTemplateName": "test_launch_template", "Version": "1"},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=True,
|
||||
)
|
||||
expected_launch_template = {
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "test_launch_template",
|
||||
"Version": "1",
|
||||
}
|
||||
|
||||
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group["AutoScalingGroupName"].should.equal("test_asg")
|
||||
group["LaunchTemplate"].should.equal(expected_launch_template)
|
||||
group.should_not.have.key("LaunchConfigurationName")
|
||||
group["AvailabilityZones"].should.equal(["us-east-1a"])
|
||||
group["VPCZoneIdentifier"].should.equal(mocked_networking["subnet1"])
|
||||
group["NewInstancesProtectedFromScaleIn"].should.equal(True)
|
||||
for instance in group["Instances"]:
|
||||
instance["LaunchTemplate"].should.equal(expected_launch_template)
|
||||
instance.should_not.have.key("LaunchConfigurationName")
|
||||
instance["AvailabilityZone"].should.equal("us-east-1a")
|
||||
instance["ProtectedFromScaleIn"].should.equal(True)
|
||||
instance["InstanceType"].should.equal("t2.micro")
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_describe_autoscaling_instances_boto3_launch_config():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
_ = client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration", InstanceType="t2.micro",
|
||||
)
|
||||
_ = client.create_auto_scaling_group(
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
|
|
@ -846,9 +1055,51 @@ def test_describe_autoscaling_instances_boto3():
|
|||
response = client.describe_auto_scaling_instances()
|
||||
len(response["AutoScalingInstances"]).should.equal(5)
|
||||
for instance in response["AutoScalingInstances"]:
|
||||
instance["LaunchConfigurationName"].should.equal("test_launch_configuration")
|
||||
instance.should_not.have.key("LaunchTemplate")
|
||||
instance["AutoScalingGroupName"].should.equal("test_asg")
|
||||
instance["AvailabilityZone"].should.equal("us-east-1a")
|
||||
instance["ProtectedFromScaleIn"].should.equal(True)
|
||||
instance["InstanceType"].should.equal("t2.micro")
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_describe_autoscaling_instances_boto3_launch_template():
|
||||
mocked_networking = setup_networking()
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={"LaunchTemplateName": "test_launch_template", "Version": "1"},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=True,
|
||||
)
|
||||
expected_launch_template = {
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "test_launch_template",
|
||||
"Version": "1",
|
||||
}
|
||||
|
||||
response = client.describe_auto_scaling_instances()
|
||||
len(response["AutoScalingInstances"]).should.equal(5)
|
||||
for instance in response["AutoScalingInstances"]:
|
||||
instance["LaunchTemplate"].should.equal(expected_launch_template)
|
||||
instance.should_not.have.key("LaunchConfigurationName")
|
||||
instance["AutoScalingGroupName"].should.equal("test_asg")
|
||||
instance["AvailabilityZone"].should.equal("us-east-1a")
|
||||
instance["ProtectedFromScaleIn"].should.equal(True)
|
||||
instance["InstanceType"].should.equal("t2.micro")
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
|
|
@ -885,13 +1136,16 @@ def test_describe_autoscaling_instances_instanceid_filter():
|
|||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_update_autoscaling_group_boto3():
|
||||
def test_update_autoscaling_group_boto3_launch_config():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
_ = client.create_launch_configuration(
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration"
|
||||
)
|
||||
_ = client.create_auto_scaling_group(
|
||||
client.create_launch_configuration(
|
||||
LaunchConfigurationName="test_launch_configuration_new"
|
||||
)
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration",
|
||||
MinSize=0,
|
||||
|
|
@ -901,8 +1155,9 @@ def test_update_autoscaling_group_boto3():
|
|||
NewInstancesProtectedFromScaleIn=True,
|
||||
)
|
||||
|
||||
_ = client.update_auto_scaling_group(
|
||||
client.update_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchConfigurationName="test_launch_configuration_new",
|
||||
MinSize=1,
|
||||
VPCZoneIdentifier="{subnet1},{subnet2}".format(
|
||||
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
|
||||
|
|
@ -912,6 +1167,64 @@ def test_update_autoscaling_group_boto3():
|
|||
|
||||
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group["LaunchConfigurationName"].should.equal("test_launch_configuration_new")
|
||||
group["MinSize"].should.equal(1)
|
||||
set(group["AvailabilityZones"]).should.equal({"us-east-1a", "us-east-1b"})
|
||||
group["NewInstancesProtectedFromScaleIn"].should.equal(False)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_update_autoscaling_group_boto3_launch_template():
|
||||
mocked_networking = setup_networking()
|
||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||
ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-0cc293023f983ed53",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)
|
||||
template = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="test_launch_template_new",
|
||||
LaunchTemplateData={
|
||||
"ImageId": "ami-1ea5b10a3d8867db4",
|
||||
"InstanceType": "t2.micro",
|
||||
},
|
||||
)["LaunchTemplate"]
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={"LaunchTemplateName": "test_launch_template", "Version": "1"},
|
||||
MinSize=0,
|
||||
MaxSize=20,
|
||||
DesiredCapacity=5,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=True,
|
||||
)
|
||||
|
||||
client.update_auto_scaling_group(
|
||||
AutoScalingGroupName="test_asg",
|
||||
LaunchTemplate={
|
||||
"LaunchTemplateName": "test_launch_template_new",
|
||||
"Version": "1",
|
||||
},
|
||||
MinSize=1,
|
||||
VPCZoneIdentifier="{subnet1},{subnet2}".format(
|
||||
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
|
||||
),
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
|
||||
expected_launch_template = {
|
||||
"LaunchTemplateId": template["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "test_launch_template_new",
|
||||
"Version": "1",
|
||||
}
|
||||
|
||||
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group["LaunchTemplate"].should.equal(expected_launch_template)
|
||||
group["MinSize"].should.equal(1)
|
||||
set(group["AvailabilityZones"]).should.equal({"us-east-1a", "us-east-1b"})
|
||||
group["NewInstancesProtectedFromScaleIn"].should.equal(False)
|
||||
|
|
@ -966,7 +1279,7 @@ def test_update_autoscaling_group_max_size_desired_capacity_change():
|
|||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_autoscaling_taqs_update_boto3():
|
||||
def test_autoscaling_tags_update_boto3():
|
||||
mocked_networking = setup_networking()
|
||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||
_ = client.create_launch_configuration(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue