AutoScaling: create_auto_scaling_group() now supports the MixedInstancesPolicy-parameter (#5433)
This commit is contained in:
parent
bd051f4f32
commit
2c98b7574b
@ -368,6 +368,8 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
autoscaling_backend,
|
||||
ec2_backend,
|
||||
tags,
|
||||
mixed_instance_policy,
|
||||
capacity_rebalance,
|
||||
new_instances_protected_from_scale_in=False,
|
||||
):
|
||||
self.autoscaling_backend = autoscaling_backend
|
||||
@ -376,6 +378,7 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
self._id = str(uuid4())
|
||||
self.region = self.autoscaling_backend.region_name
|
||||
self.account_id = self.autoscaling_backend.account_id
|
||||
self.service_linked_role = f"arn:aws:iam::{self.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
|
||||
|
||||
self._set_azs_and_vpcs(availability_zones, vpc_zone_identifier)
|
||||
|
||||
@ -385,7 +388,10 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
self.launch_template = None
|
||||
self.launch_config = None
|
||||
|
||||
self._set_launch_configuration(launch_config_name, launch_template)
|
||||
self._set_launch_configuration(
|
||||
launch_config_name, launch_template, mixed_instance_policy
|
||||
)
|
||||
self.mixed_instance_policy = mixed_instance_policy
|
||||
|
||||
self.default_cooldown = (
|
||||
default_cooldown if default_cooldown else DEFAULT_COOLDOWN
|
||||
@ -395,6 +401,7 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
self.load_balancers = load_balancers
|
||||
self.target_group_arns = target_group_arns
|
||||
self.placement_group = placement_group
|
||||
self.capacity_rebalance = capacity_rebalance
|
||||
self.termination_policies = termination_policies or ["Default"]
|
||||
self.new_instances_protected_from_scale_in = (
|
||||
new_instances_protected_from_scale_in
|
||||
@ -458,16 +465,29 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
self.availability_zones = availability_zones
|
||||
self.vpc_zone_identifier = vpc_zone_identifier
|
||||
|
||||
def _set_launch_configuration(self, launch_config_name, launch_template):
|
||||
def _set_launch_configuration(
|
||||
self, launch_config_name, launch_template, mixed_instance_policy
|
||||
):
|
||||
if launch_config_name:
|
||||
self.launch_config = self.autoscaling_backend.launch_configurations[
|
||||
launch_config_name
|
||||
]
|
||||
self.launch_config_name = launch_config_name
|
||||
|
||||
if launch_template:
|
||||
launch_template_id = launch_template.get("launch_template_id")
|
||||
launch_template_name = launch_template.get("launch_template_name")
|
||||
if launch_template or mixed_instance_policy:
|
||||
if launch_template:
|
||||
launch_template_id = launch_template.get("launch_template_id")
|
||||
launch_template_name = launch_template.get("launch_template_name")
|
||||
self.launch_template_version = (
|
||||
launch_template.get("version") or "$Default"
|
||||
)
|
||||
else:
|
||||
spec = mixed_instance_policy["LaunchTemplate"][
|
||||
"LaunchTemplateSpecification"
|
||||
]
|
||||
launch_template_id = spec.get("LaunchTemplateId")
|
||||
launch_template_name = spec.get("LaunchTemplateName")
|
||||
self.launch_template_version = spec.get("Version") or "$Default"
|
||||
|
||||
if not (launch_template_id or launch_template_name) or (
|
||||
launch_template_id and launch_template_name
|
||||
@ -484,7 +504,6 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
self.launch_template = self.ec2_backend.get_launch_template_by_name(
|
||||
launch_template_name
|
||||
)
|
||||
self.launch_template_version = launch_template.get("version") or "$Default"
|
||||
|
||||
@staticmethod
|
||||
def __set_string_propagate_at_launch_booleans_on_tags(tags):
|
||||
@ -637,7 +656,9 @@ class FakeAutoScalingGroup(CloudFormationModel):
|
||||
if max_size is not None and max_size < len(self.instance_states):
|
||||
desired_capacity = max_size
|
||||
|
||||
self._set_launch_configuration(launch_config_name, launch_template)
|
||||
self._set_launch_configuration(
|
||||
launch_config_name, launch_template, mixed_instance_policy=None
|
||||
)
|
||||
|
||||
if health_check_period is not None:
|
||||
self.health_check_period = health_check_period
|
||||
@ -909,8 +930,10 @@ class AutoScalingBackend(BaseBackend):
|
||||
placement_group,
|
||||
termination_policies,
|
||||
tags,
|
||||
capacity_rebalance=False,
|
||||
new_instances_protected_from_scale_in=False,
|
||||
instance_id=None,
|
||||
mixed_instance_policy=None,
|
||||
):
|
||||
max_size = self.make_int(max_size)
|
||||
min_size = self.make_int(min_size)
|
||||
@ -921,9 +944,13 @@ class AutoScalingBackend(BaseBackend):
|
||||
else:
|
||||
health_check_period = self.make_int(health_check_period)
|
||||
|
||||
# TODO: Add MixedInstancesPolicy once implemented.
|
||||
# Verify only a single launch config-like parameter is provided.
|
||||
params = [launch_config_name, launch_template, instance_id]
|
||||
params = [
|
||||
launch_config_name,
|
||||
launch_template,
|
||||
instance_id,
|
||||
mixed_instance_policy,
|
||||
]
|
||||
num_params = sum([1 for param in params if param])
|
||||
|
||||
if num_params != 1:
|
||||
@ -962,6 +989,8 @@ class AutoScalingBackend(BaseBackend):
|
||||
ec2_backend=self.ec2_backend,
|
||||
tags=tags,
|
||||
new_instances_protected_from_scale_in=new_instances_protected_from_scale_in,
|
||||
mixed_instance_policy=mixed_instance_policy,
|
||||
capacity_rebalance=capacity_rebalance,
|
||||
)
|
||||
|
||||
self.autoscaling_groups[name] = group
|
||||
|
@ -80,6 +80,7 @@ class AutoScalingResponse(BaseResponse):
|
||||
return template.render()
|
||||
|
||||
def create_auto_scaling_group(self):
|
||||
params = self._get_params()
|
||||
self.autoscaling_backend.create_auto_scaling_group(
|
||||
name=self._get_param("AutoScalingGroupName"),
|
||||
availability_zones=self._get_multi_param("AvailabilityZones.member"),
|
||||
@ -89,6 +90,7 @@ class AutoScalingResponse(BaseResponse):
|
||||
instance_id=self._get_param("InstanceId"),
|
||||
launch_config_name=self._get_param("LaunchConfigurationName"),
|
||||
launch_template=self._get_dict_param("LaunchTemplate."),
|
||||
mixed_instance_policy=params.get("MixedInstancesPolicy"),
|
||||
vpc_zone_identifier=self._get_param("VPCZoneIdentifier"),
|
||||
default_cooldown=self._get_int_param("DefaultCooldown"),
|
||||
health_check_period=self._get_int_param("HealthCheckGracePeriod"),
|
||||
@ -98,6 +100,7 @@ class AutoScalingResponse(BaseResponse):
|
||||
placement_group=self._get_param("PlacementGroup"),
|
||||
termination_policies=self._get_multi_param("TerminationPolicies.member"),
|
||||
tags=self._get_list_prefix("Tags.member"),
|
||||
capacity_rebalance=self._get_bool_param("CapacityRebalance"),
|
||||
new_instances_protected_from_scale_in=self._get_bool_param(
|
||||
"NewInstancesProtectedFromScaleIn", False
|
||||
),
|
||||
@ -748,6 +751,30 @@ DESCRIBE_AUTOSCALING_GROUPS_TEMPLATE = """<DescribeAutoScalingGroupsResponse xml
|
||||
<CreatedTime>2013-05-06T17:47:15.107Z</CreatedTime>
|
||||
{% if group.launch_config_name %}
|
||||
<LaunchConfigurationName>{{ group.launch_config_name }}</LaunchConfigurationName>
|
||||
{% elif group.mixed_instance_policy %}
|
||||
<MixedInstancesPolicy>
|
||||
<LaunchTemplate>
|
||||
<LaunchTemplateSpecification>
|
||||
<LaunchTemplateId>{{ group.launch_template.id }}</LaunchTemplateId>
|
||||
<Version>{{ group.launch_template_version }}</Version>
|
||||
<LaunchTemplateName>{{ group.launch_template.name }}</LaunchTemplateName>
|
||||
</LaunchTemplateSpecification>
|
||||
{% if group.mixed_instance_policy.get("LaunchTemplate", {}).get("Overrides", []) %}
|
||||
<Overrides>
|
||||
{% for member in group.mixed_instance_policy.get("LaunchTemplate", {}).get("Overrides", []) %}
|
||||
<member>
|
||||
{% if member.get("InstanceType") %}
|
||||
<InstanceType>{{ member.get("InstanceType") }}</InstanceType>
|
||||
{% endif %}
|
||||
{% if member.get("WeightedCapacity") %}
|
||||
<WeightedCapacity>{{ member.get("WeightedCapacity") }}</WeightedCapacity>
|
||||
{% endif %}
|
||||
</member>
|
||||
{% endfor %}
|
||||
</Overrides>
|
||||
{% endif %}
|
||||
</LaunchTemplate>
|
||||
</MixedInstancesPolicy>
|
||||
{% elif group.launch_template %}
|
||||
<LaunchTemplate>
|
||||
<LaunchTemplateId>{{ group.launch_template.id }}</LaunchTemplateId>
|
||||
@ -777,6 +804,7 @@ DESCRIBE_AUTOSCALING_GROUPS_TEMPLATE = """<DescribeAutoScalingGroupsResponse xml
|
||||
{% endfor %}
|
||||
</Instances>
|
||||
<DesiredCapacity>{{ group.desired_capacity }}</DesiredCapacity>
|
||||
<CapacityRebalance>{{ 'true' if group.capacity_rebalance else 'false' }}</CapacityRebalance>
|
||||
<AvailabilityZones>
|
||||
{% for availability_zone in group.availability_zones %}
|
||||
<member>{{ availability_zone }}</member>
|
||||
@ -833,6 +861,7 @@ DESCRIBE_AUTOSCALING_GROUPS_TEMPLATE = """<DescribeAutoScalingGroupsResponse xml
|
||||
{% endfor %}
|
||||
</EnabledMetrics>
|
||||
{% endif %}
|
||||
<ServiceLinkedRoleARN>{{ group.service_linked_role }}</ServiceLinkedRoleARN>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</AutoScalingGroups>
|
||||
|
@ -11,6 +11,14 @@ autoscaling:
|
||||
- TestAccAutoScalingAttachment
|
||||
- TestAccAutoScalingGroupDataSource
|
||||
- TestAccAutoScalingGroupTag
|
||||
- TestAccAutoScalingGroup_basic
|
||||
- TestAccAutoScalingGroup_disappears
|
||||
- TestAccAutoScalingGroup_nameGenerated
|
||||
- TestAccAutoScalingGroup_namePrefix
|
||||
- TestAccAutoScalingGroup_enablingMetrics
|
||||
- TestAccAutoScalingGroup_suspendingProcesses
|
||||
- TestAccAutoScalingGroup_mixedInstancesPolicy
|
||||
- TestAccAutoScalingGroup_MixedInstancesPolicy_capacityRebalance
|
||||
- TestAccAutoScalingLaunchConfigurationDataSource
|
||||
- TestAccAutoScalingLaunchConfiguration_
|
||||
batch:
|
||||
|
@ -61,22 +61,6 @@ def test_create_autoscaling_group_from_instance():
|
||||
MinSize=1,
|
||||
MaxSize=3,
|
||||
DesiredCapacity=2,
|
||||
Tags=[
|
||||
{
|
||||
"ResourceId": "test_asg",
|
||||
"ResourceType": "auto-scaling-group",
|
||||
"Key": "propogated-tag-key",
|
||||
"Value": "propagate-tag-value",
|
||||
"PropagateAtLaunch": True,
|
||||
},
|
||||
{
|
||||
"ResourceId": "test_asg",
|
||||
"ResourceType": "auto-scaling-group",
|
||||
"Key": "not-propogated-tag-key",
|
||||
"Value": "not-propagate-tag-value",
|
||||
"PropagateAtLaunch": False,
|
||||
},
|
||||
],
|
||||
VPCZoneIdentifier=mocked_instance_with_networking["subnet1"],
|
||||
NewInstancesProtectedFromScaleIn=False,
|
||||
)
|
||||
@ -874,6 +858,116 @@ def test_create_autoscaling_policy_with_predictive_scaling_config():
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_create_auto_scaling_group_with_mixed_instances_policy():
|
||||
mocked_networking = setup_networking(region_name="eu-west-1")
|
||||
client = boto3.client("autoscaling", region_name="eu-west-1")
|
||||
ec2_client = boto3.client("ec2", region_name="eu-west-1")
|
||||
asg_name = "asg_test"
|
||||
|
||||
lt = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="launchie",
|
||||
LaunchTemplateData={"ImageId": EXAMPLE_AMI_ID},
|
||||
)["LaunchTemplate"]
|
||||
client.create_auto_scaling_group(
|
||||
MixedInstancesPolicy={
|
||||
"LaunchTemplate": {
|
||||
"LaunchTemplateSpecification": {
|
||||
"LaunchTemplateName": "launchie",
|
||||
"Version": "$DEFAULT",
|
||||
}
|
||||
}
|
||||
},
|
||||
AutoScalingGroupName=asg_name,
|
||||
MinSize=2,
|
||||
MaxSize=2,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
)
|
||||
|
||||
# Assert we can describe MixedInstancesPolicy
|
||||
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=[asg_name])
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group.should.have.key("MixedInstancesPolicy").equals(
|
||||
{
|
||||
"LaunchTemplate": {
|
||||
"LaunchTemplateSpecification": {
|
||||
"LaunchTemplateId": lt["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "launchie",
|
||||
"Version": "$DEFAULT",
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# Assert the LaunchTemplate is known for the resulting instances
|
||||
response = client.describe_auto_scaling_instances()
|
||||
len(response["AutoScalingInstances"]).should.equal(2)
|
||||
for instance in response["AutoScalingInstances"]:
|
||||
instance["LaunchTemplate"].should.equal(
|
||||
{
|
||||
"LaunchTemplateId": lt["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "launchie",
|
||||
"Version": "$DEFAULT",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
@mock_ec2
|
||||
def test_create_auto_scaling_group_with_mixed_instances_policy_overrides():
|
||||
mocked_networking = setup_networking(region_name="eu-west-1")
|
||||
client = boto3.client("autoscaling", region_name="eu-west-1")
|
||||
ec2_client = boto3.client("ec2", region_name="eu-west-1")
|
||||
asg_name = "asg_test"
|
||||
|
||||
lt = ec2_client.create_launch_template(
|
||||
LaunchTemplateName="launchie",
|
||||
LaunchTemplateData={"ImageId": EXAMPLE_AMI_ID},
|
||||
)["LaunchTemplate"]
|
||||
client.create_auto_scaling_group(
|
||||
MixedInstancesPolicy={
|
||||
"LaunchTemplate": {
|
||||
"LaunchTemplateSpecification": {
|
||||
"LaunchTemplateName": "launchie",
|
||||
"Version": "$DEFAULT",
|
||||
},
|
||||
"Overrides": [
|
||||
{
|
||||
"InstanceType": "t2.medium",
|
||||
"WeightedCapacity": "50",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
AutoScalingGroupName=asg_name,
|
||||
MinSize=2,
|
||||
MaxSize=2,
|
||||
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||
)
|
||||
|
||||
# Assert we can describe MixedInstancesPolicy
|
||||
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=[asg_name])
|
||||
group = response["AutoScalingGroups"][0]
|
||||
group.should.have.key("MixedInstancesPolicy").equals(
|
||||
{
|
||||
"LaunchTemplate": {
|
||||
"LaunchTemplateSpecification": {
|
||||
"LaunchTemplateId": lt["LaunchTemplateId"],
|
||||
"LaunchTemplateName": "launchie",
|
||||
"Version": "$DEFAULT",
|
||||
},
|
||||
"Overrides": [
|
||||
{
|
||||
"InstanceType": "t2.medium",
|
||||
"WeightedCapacity": "50",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@mock_autoscaling
|
||||
def test_set_instance_protection():
|
||||
mocked_networking = setup_networking()
|
||||
|
@ -44,6 +44,20 @@ class TestAutoScalingGroup(TestCase):
|
||||
group["TerminationPolicies"].should.equal(["Default"])
|
||||
group["Tags"].should.equal([])
|
||||
|
||||
def test_create_autoscaling_group__additional_params(self):
|
||||
self.as_client.create_auto_scaling_group(
|
||||
AutoScalingGroupName="tester_group",
|
||||
MinSize=1,
|
||||
MaxSize=2,
|
||||
LaunchConfigurationName=self.lc_name,
|
||||
CapacityRebalance=True,
|
||||
VPCZoneIdentifier=self.mocked_networking["subnet1"],
|
||||
)
|
||||
|
||||
group = self.as_client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
||||
group["AutoScalingGroupName"].should.equal("tester_group")
|
||||
group["CapacityRebalance"].should.equal(True)
|
||||
|
||||
def test_list_many_autoscaling_groups(self):
|
||||
|
||||
for i in range(51):
|
||||
|
Loading…
Reference in New Issue
Block a user