493 lines
17 KiB
Python
493 lines
17 KiB
Python
import json
|
|
|
|
import boto3
|
|
|
|
from moto import mock_aws
|
|
from tests import EXAMPLE_AMI_ID
|
|
|
|
from .utils import setup_networking
|
|
|
|
|
|
@mock_aws
|
|
def test_launch_configuration():
|
|
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
|
|
|
stack_name = "test-launch-configuration"
|
|
|
|
cf_template = """
|
|
Resources:
|
|
LaunchConfiguration:
|
|
Type: AWS::AutoScaling::LaunchConfiguration
|
|
Properties:
|
|
ImageId: {0}
|
|
InstanceType: t2.micro
|
|
LaunchConfigurationName: test_launch_configuration
|
|
Outputs:
|
|
LaunchConfigurationName:
|
|
Value: !Ref LaunchConfiguration
|
|
""".strip().format(
|
|
EXAMPLE_AMI_ID
|
|
)
|
|
|
|
cf_client.create_stack(StackName=stack_name, TemplateBody=cf_template)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_launch_configuration"
|
|
|
|
lc = client.describe_launch_configurations()["LaunchConfigurations"][0]
|
|
assert lc["LaunchConfigurationName"] == "test_launch_configuration"
|
|
assert lc["ImageId"] == EXAMPLE_AMI_ID
|
|
assert lc["InstanceType"] == "t2.micro"
|
|
|
|
cf_template = """
|
|
Resources:
|
|
LaunchConfiguration:
|
|
Type: AWS::AutoScaling::LaunchConfiguration
|
|
Properties:
|
|
ImageId: {0}
|
|
InstanceType: m5.large
|
|
LaunchConfigurationName: test_launch_configuration
|
|
Outputs:
|
|
LaunchConfigurationName:
|
|
Value: !Ref LaunchConfiguration
|
|
""".strip().format(
|
|
EXAMPLE_AMI_ID
|
|
)
|
|
|
|
cf_client.update_stack(StackName=stack_name, TemplateBody=cf_template)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_launch_configuration"
|
|
|
|
lc = client.describe_launch_configurations()["LaunchConfigurations"][0]
|
|
assert lc["LaunchConfigurationName"] == "test_launch_configuration"
|
|
assert lc["ImageId"] == EXAMPLE_AMI_ID
|
|
assert lc["InstanceType"] == "m5.large"
|
|
|
|
|
|
@mock_aws
|
|
def test_autoscaling_group_from_launch_config():
|
|
subnet_id = setup_networking()["subnet1"]
|
|
|
|
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
|
|
|
client.create_launch_configuration(
|
|
LaunchConfigurationName="test_launch_configuration",
|
|
InstanceType="t2.micro",
|
|
ImageId=EXAMPLE_AMI_ID,
|
|
)
|
|
stack_name = "test-auto-scaling-group"
|
|
|
|
cf_template = """
|
|
Parameters:
|
|
SubnetId:
|
|
Type: AWS::EC2::Subnet::Id
|
|
Resources:
|
|
AutoScalingGroup:
|
|
Type: AWS::AutoScaling::AutoScalingGroup
|
|
Properties:
|
|
AutoScalingGroupName: test_auto_scaling_group
|
|
AvailabilityZones:
|
|
- us-east-1a
|
|
LaunchConfigurationName: test_launch_configuration
|
|
MaxSize: "5"
|
|
MinSize: "1"
|
|
VPCZoneIdentifier:
|
|
- !Ref SubnetId
|
|
Outputs:
|
|
AutoScalingGroupName:
|
|
Value: !Ref AutoScalingGroup
|
|
""".strip()
|
|
|
|
cf_client.create_stack(
|
|
StackName=stack_name,
|
|
TemplateBody=cf_template,
|
|
Parameters=[{"ParameterKey": "SubnetId", "ParameterValue": subnet_id}],
|
|
)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_auto_scaling_group"
|
|
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["AutoScalingGroupName"] == "test_auto_scaling_group"
|
|
assert asg["MinSize"] == 1
|
|
assert asg["MaxSize"] == 5
|
|
assert asg["LaunchConfigurationName"] == "test_launch_configuration"
|
|
|
|
client.create_launch_configuration(
|
|
LaunchConfigurationName="test_launch_configuration_new",
|
|
InstanceType="t2.micro",
|
|
ImageId=EXAMPLE_AMI_ID,
|
|
)
|
|
|
|
cf_template = """
|
|
Parameters:
|
|
SubnetId:
|
|
Type: AWS::EC2::Subnet::Id
|
|
Resources:
|
|
AutoScalingGroup:
|
|
Type: AWS::AutoScaling::AutoScalingGroup
|
|
Properties:
|
|
AutoScalingGroupName: test_auto_scaling_group
|
|
AvailabilityZones:
|
|
- us-east-1a
|
|
LaunchConfigurationName: test_launch_configuration_new
|
|
MaxSize: "6"
|
|
MinSize: "2"
|
|
VPCZoneIdentifier:
|
|
- !Ref SubnetId
|
|
Outputs:
|
|
AutoScalingGroupName:
|
|
Value: !Ref AutoScalingGroup
|
|
""".strip()
|
|
|
|
cf_client.update_stack(
|
|
StackName=stack_name,
|
|
TemplateBody=cf_template,
|
|
Parameters=[{"ParameterKey": "SubnetId", "ParameterValue": subnet_id}],
|
|
)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_auto_scaling_group"
|
|
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["AutoScalingGroupName"] == "test_auto_scaling_group"
|
|
assert asg["MinSize"] == 2
|
|
assert asg["MaxSize"] == 6
|
|
assert asg["LaunchConfigurationName"] == "test_launch_configuration_new"
|
|
|
|
|
|
@mock_aws
|
|
def test_autoscaling_group_from_launch_template():
|
|
subnet_id = setup_networking()["subnet1"]
|
|
|
|
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
|
|
|
template_response = ec2_client.create_launch_template(
|
|
LaunchTemplateName="test_launch_template",
|
|
LaunchTemplateData={"ImageId": EXAMPLE_AMI_ID, "InstanceType": "t2.micro"},
|
|
)
|
|
launch_template_id = template_response["LaunchTemplate"]["LaunchTemplateId"]
|
|
stack_name = "test-auto-scaling-group"
|
|
|
|
cf_template = """
|
|
Parameters:
|
|
SubnetId:
|
|
Type: AWS::EC2::Subnet::Id
|
|
LaunchTemplateId:
|
|
Type: String
|
|
Resources:
|
|
AutoScalingGroup:
|
|
Type: AWS::AutoScaling::AutoScalingGroup
|
|
Properties:
|
|
AutoScalingGroupName: test_auto_scaling_group
|
|
AvailabilityZones:
|
|
- us-east-1a
|
|
LaunchTemplate:
|
|
LaunchTemplateId: !Ref LaunchTemplateId
|
|
Version: "1"
|
|
MaxSize: "5"
|
|
MinSize: "1"
|
|
VPCZoneIdentifier:
|
|
- !Ref SubnetId
|
|
Outputs:
|
|
AutoScalingGroupName:
|
|
Value: !Ref AutoScalingGroup
|
|
""".strip()
|
|
|
|
cf_client.create_stack(
|
|
StackName=stack_name,
|
|
TemplateBody=cf_template,
|
|
Parameters=[
|
|
{"ParameterKey": "SubnetId", "ParameterValue": subnet_id},
|
|
{"ParameterKey": "LaunchTemplateId", "ParameterValue": launch_template_id},
|
|
],
|
|
)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_auto_scaling_group"
|
|
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["AutoScalingGroupName"] == "test_auto_scaling_group"
|
|
assert asg["MinSize"] == 1
|
|
assert asg["MaxSize"] == 5
|
|
lt = asg["LaunchTemplate"]
|
|
assert lt["LaunchTemplateId"] == launch_template_id
|
|
assert lt["LaunchTemplateName"] == "test_launch_template"
|
|
assert lt["Version"] == "1"
|
|
|
|
template_response = ec2_client.create_launch_template(
|
|
LaunchTemplateName="test_launch_template_new",
|
|
LaunchTemplateData={"ImageId": EXAMPLE_AMI_ID, "InstanceType": "m5.large"},
|
|
)
|
|
launch_template_id = template_response["LaunchTemplate"]["LaunchTemplateId"]
|
|
|
|
cf_template = """
|
|
Parameters:
|
|
SubnetId:
|
|
Type: AWS::EC2::Subnet::Id
|
|
LaunchTemplateId:
|
|
Type: String
|
|
Resources:
|
|
AutoScalingGroup:
|
|
Type: AWS::AutoScaling::AutoScalingGroup
|
|
Properties:
|
|
AutoScalingGroupName: test_auto_scaling_group
|
|
AvailabilityZones:
|
|
- us-east-1a
|
|
LaunchTemplate:
|
|
LaunchTemplateId: !Ref LaunchTemplateId
|
|
Version: "1"
|
|
MaxSize: "6"
|
|
MinSize: "2"
|
|
VPCZoneIdentifier:
|
|
- !Ref SubnetId
|
|
Outputs:
|
|
AutoScalingGroupName:
|
|
Value: !Ref AutoScalingGroup
|
|
""".strip()
|
|
|
|
cf_client.update_stack(
|
|
StackName=stack_name,
|
|
TemplateBody=cf_template,
|
|
Parameters=[
|
|
{"ParameterKey": "SubnetId", "ParameterValue": subnet_id},
|
|
{"ParameterKey": "LaunchTemplateId", "ParameterValue": launch_template_id},
|
|
],
|
|
)
|
|
stack = cf_client.describe_stacks(StackName=stack_name)["Stacks"][0]
|
|
assert stack["Outputs"][0]["OutputValue"] == "test_auto_scaling_group"
|
|
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["AutoScalingGroupName"] == "test_auto_scaling_group"
|
|
assert asg["MinSize"] == 2
|
|
assert asg["MaxSize"] == 6
|
|
lt = asg["LaunchTemplate"]
|
|
assert lt["LaunchTemplateId"] == launch_template_id
|
|
assert lt["LaunchTemplateName"] == "test_launch_template_new"
|
|
assert lt["Version"] == "1"
|
|
|
|
|
|
@mock_aws
|
|
def test_autoscaling_group_with_elb():
|
|
web_setup_template = {
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
"Resources": {
|
|
"my-as-group": {
|
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
|
"Properties": {
|
|
"AvailabilityZones": ["us-east-1a"],
|
|
"LaunchConfigurationName": {"Ref": "my-launch-config"},
|
|
"MinSize": "2",
|
|
"MaxSize": "2",
|
|
"DesiredCapacity": "2",
|
|
"LoadBalancerNames": [{"Ref": "my-elb"}],
|
|
"Tags": [
|
|
{
|
|
"Key": "propagated-test-tag",
|
|
"Value": "propagated-test-tag-value",
|
|
"PropagateAtLaunch": True,
|
|
},
|
|
{
|
|
"Key": "not-propagated-test-tag",
|
|
"Value": "not-propagated-test-tag-value",
|
|
"PropagateAtLaunch": False,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
"ScheduledAction": {
|
|
"Type": "AWS::AutoScaling::ScheduledAction",
|
|
"Properties": {
|
|
"AutoScalingGroupName": "test-scaling-group",
|
|
"DesiredCapacity": 10,
|
|
"EndTime": "2022-08-01T00:00:00Z",
|
|
"MaxSize": 15,
|
|
"MinSize": 5,
|
|
"Recurrence": "* * * * *",
|
|
"StartTime": "2022-07-01T00:00:00Z",
|
|
"TimeZone": "Etc/UTC",
|
|
},
|
|
},
|
|
"my-launch-config": {
|
|
"Type": "AWS::AutoScaling::LaunchConfiguration",
|
|
"Properties": {
|
|
"ImageId": EXAMPLE_AMI_ID,
|
|
"InstanceType": "t2.medium",
|
|
"UserData": "some user data",
|
|
},
|
|
},
|
|
"my-elb": {
|
|
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
|
|
"Properties": {
|
|
"AvailabilityZones": ["us-east-1a"],
|
|
"Listeners": [
|
|
{
|
|
"LoadBalancerPort": "80",
|
|
"InstancePort": "80",
|
|
"Protocol": "HTTP",
|
|
}
|
|
],
|
|
"LoadBalancerName": "my-elb",
|
|
"HealthCheck": {
|
|
"Target": "HTTP:80",
|
|
"HealthyThreshold": "3",
|
|
"UnhealthyThreshold": "5",
|
|
"Interval": "30",
|
|
"Timeout": "5",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
web_setup_template_json = json.dumps(web_setup_template)
|
|
|
|
cf = boto3.client("cloudformation", region_name="us-east-1")
|
|
ec2 = boto3.client("ec2", region_name="us-east-1")
|
|
elb = boto3.client("elb", region_name="us-east-1")
|
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
|
|
|
cf.create_stack(StackName="web_stack", TemplateBody=web_setup_template_json)
|
|
|
|
autoscale_group = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
asg_name = autoscale_group["AutoScalingGroupName"]
|
|
assert "my-launch-config" in autoscale_group["LaunchConfigurationName"]
|
|
assert autoscale_group["LoadBalancerNames"] == ["my-elb"]
|
|
assert len(autoscale_group["Tags"]) == 2
|
|
assert {
|
|
"ResourceId": asg_name,
|
|
"ResourceType": "auto-scaling-group",
|
|
"Key": "propagated-test-tag",
|
|
"Value": "propagated-test-tag-value",
|
|
"PropagateAtLaunch": True,
|
|
} in autoscale_group["Tags"]
|
|
assert {
|
|
"ResourceId": asg_name,
|
|
"ResourceType": "auto-scaling-group",
|
|
"Key": "not-propagated-test-tag",
|
|
"Value": "not-propagated-test-tag-value",
|
|
"PropagateAtLaunch": False,
|
|
} in autoscale_group["Tags"]
|
|
|
|
tags = client.describe_tags(
|
|
Filters=[{"Name": "auto-scaling-group", "Values": [asg_name]}]
|
|
)["Tags"]
|
|
assert tags == autoscale_group["Tags"]
|
|
|
|
# Confirm the Launch config was actually created
|
|
assert len(client.describe_launch_configurations()["LaunchConfigurations"]) == 1
|
|
|
|
# Confirm the ELB was actually created
|
|
assert len(elb.describe_load_balancers()["LoadBalancerDescriptions"]) == 1
|
|
|
|
resources = cf.list_stack_resources(StackName="web_stack")["StackResourceSummaries"]
|
|
as_group_resource = [
|
|
resource
|
|
for resource in resources
|
|
if resource["ResourceType"] == "AWS::AutoScaling::AutoScalingGroup"
|
|
][0]
|
|
assert "my-as-group" in as_group_resource["PhysicalResourceId"]
|
|
|
|
launch_config_resource = [
|
|
resource
|
|
for resource in resources
|
|
if resource["ResourceType"] == "AWS::AutoScaling::LaunchConfiguration"
|
|
][0]
|
|
assert "my-launch-config" in launch_config_resource["PhysicalResourceId"]
|
|
|
|
elb_resource = [
|
|
resource
|
|
for resource in resources
|
|
if resource["ResourceType"] == "AWS::ElasticLoadBalancing::LoadBalancer"
|
|
][0]
|
|
assert "my-elb" in elb_resource["PhysicalResourceId"]
|
|
|
|
# confirm the instances were created with the right tags
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
|
|
assert len(reservations) == 1
|
|
assert len(reservations[0]["Instances"]) == 2
|
|
for instance in reservations[0]["Instances"]:
|
|
tag_keys = [t["Key"] for t in instance["Tags"]]
|
|
assert "propagated-test-tag" in tag_keys
|
|
assert "not-propagated-test-tag" not in tag_keys
|
|
|
|
# confirm scheduled scaling action was created
|
|
response = client.describe_scheduled_actions(
|
|
AutoScalingGroupName="test-scaling-group"
|
|
)["ScheduledUpdateGroupActions"]
|
|
assert len(response) == 1
|
|
|
|
|
|
@mock_aws
|
|
def test_autoscaling_group_update():
|
|
asg_template = {
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
"Resources": {
|
|
"my-as-group": {
|
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
|
"Properties": {
|
|
"AvailabilityZones": ["us-west-1a"],
|
|
"LaunchConfigurationName": {"Ref": "my-launch-config"},
|
|
"MinSize": "2",
|
|
"MaxSize": "2",
|
|
"DesiredCapacity": "2",
|
|
},
|
|
},
|
|
"my-launch-config": {
|
|
"Type": "AWS::AutoScaling::LaunchConfiguration",
|
|
"Properties": {
|
|
"ImageId": EXAMPLE_AMI_ID,
|
|
"InstanceType": "t2.medium",
|
|
"UserData": "some user data",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
asg_template_json = json.dumps(asg_template)
|
|
|
|
cf = boto3.client("cloudformation", region_name="us-west-1")
|
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
|
client = boto3.client("autoscaling", region_name="us-west-1")
|
|
cf.create_stack(StackName="asg_stack", TemplateBody=asg_template_json)
|
|
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["MinSize"] == 2
|
|
assert asg["MaxSize"] == 2
|
|
assert asg["DesiredCapacity"] == 2
|
|
|
|
asg_template["Resources"]["my-as-group"]["Properties"]["MaxSize"] = 3
|
|
asg_template["Resources"]["my-as-group"]["Properties"]["Tags"] = [
|
|
{
|
|
"Key": "propagated-test-tag",
|
|
"Value": "propagated-test-tag-value",
|
|
"PropagateAtLaunch": True,
|
|
},
|
|
{
|
|
"Key": "not-propagated-test-tag",
|
|
"Value": "not-propagated-test-tag-value",
|
|
"PropagateAtLaunch": False,
|
|
},
|
|
]
|
|
asg_template_json = json.dumps(asg_template)
|
|
cf.update_stack(StackName="asg_stack", TemplateBody=asg_template_json)
|
|
asg = client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
|
assert asg["MinSize"] == 2
|
|
assert asg["MaxSize"] == 3
|
|
assert asg["DesiredCapacity"] == 2
|
|
|
|
# confirm the instances were created with the right tags
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
running_instance_count = 0
|
|
for res in reservations:
|
|
for instance in res["Instances"]:
|
|
if instance["State"]["Name"] == "running":
|
|
running_instance_count += 1
|
|
assert {
|
|
"Key": "propagated-test-tag",
|
|
"Value": "propagated-test-tag-value",
|
|
} in instance["Tags"]
|
|
tag_keys = [t["Key"] for t in instance["Tags"]]
|
|
assert "not-propagated-test-tag" not in tag_keys
|
|
assert running_instance_count == 2
|