CloudFormation: Implement Fn::GetAtt for AWS::EC2::LaunchTemplate (#7121)
This commit is contained in:
parent
2b077a2cca
commit
692b475501
@ -740,11 +740,9 @@ class ResourceMap(collections_abc.Mapping): # type: ignore[type-arg]
|
|||||||
new = other_template["Resources"]
|
new = other_template["Resources"]
|
||||||
|
|
||||||
resource_names_by_action = {
|
resource_names_by_action = {
|
||||||
"Add": set(new) - set(old),
|
"Add": [name for name in new if name not in old],
|
||||||
"Modify": set(
|
"Modify": [name for name in new if name in old and new[name] != old[name]],
|
||||||
name for name in new if name in old and new[name] != old[name]
|
"Remove": [name for name in old if name not in new],
|
||||||
),
|
|
||||||
"Remove": set(old) - set(new),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resource_names_by_action
|
return resource_names_by_action
|
||||||
|
@ -192,6 +192,25 @@ class LaunchTemplate(TaggedEC2Resource, CloudFormationModel):
|
|||||||
|
|
||||||
backend.delete_launch_template(name, None)
|
backend.delete_launch_template(name, None)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def has_cfn_attr(cls, attr: str) -> bool:
|
||||||
|
return attr in [
|
||||||
|
"DefaultVersionNumber",
|
||||||
|
"LaunchTemplateId",
|
||||||
|
"LatestVersionNumber",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_cfn_attribute(self, attribute_name: str) -> str:
|
||||||
|
from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
|
||||||
|
|
||||||
|
if attribute_name == "DefaultVersionNumber":
|
||||||
|
return str(self.default_version_number)
|
||||||
|
if attribute_name == "LaunchTemplateId":
|
||||||
|
return self.id
|
||||||
|
if attribute_name == "LatestVersionNumber":
|
||||||
|
return str(self.latest_version_number)
|
||||||
|
raise UnformattedGetAttTemplateException()
|
||||||
|
|
||||||
|
|
||||||
class LaunchTemplateBackend:
|
class LaunchTemplateBackend:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
247
tests/test_ec2/test_launch_templates_cloudformation.py
Normal file
247
tests/test_ec2/test_launch_templates_cloudformation.py
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
import json
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
from moto import mock_autoscaling, mock_cloudformation, mock_ec2
|
||||||
|
from tests import EXAMPLE_AMI_ID, EXAMPLE_AMI_ID2
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_cloudformation
|
||||||
|
@mock_ec2
|
||||||
|
def test_asg_with_latest_launch_template_version():
|
||||||
|
cf_client = boto3.client("cloudformation", region_name="us-west-1")
|
||||||
|
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||||
|
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||||
|
autoscaling_client = boto3.client("autoscaling", region_name="us-west-1")
|
||||||
|
|
||||||
|
subnet1 = ec2.create_subnet(
|
||||||
|
CidrBlock="10.0.1.0/24", VpcId=vpc.id, AvailabilityZone="us-west-1a"
|
||||||
|
)
|
||||||
|
|
||||||
|
subnet2 = ec2.create_subnet(
|
||||||
|
CidrBlock="10.0.2.0/24", VpcId=vpc.id, AvailabilityZone="us-west-1b"
|
||||||
|
)
|
||||||
|
|
||||||
|
autoscaling_group_name = str(uuid4())
|
||||||
|
|
||||||
|
stack_name = str(uuid4())
|
||||||
|
launch_template_name = str(uuid4())[0:6]
|
||||||
|
|
||||||
|
version_attribute = "LatestVersionNumber"
|
||||||
|
|
||||||
|
template_json = json.dumps(
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "AWS CloudFormation Template to create an ASG group with LaunchTemplate",
|
||||||
|
"Resources": {
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"Type": "AWS::EC2::LaunchTemplate",
|
||||||
|
"Properties": {
|
||||||
|
"LaunchTemplateName": launch_template_name,
|
||||||
|
"LaunchTemplateData": {
|
||||||
|
"ImageId": EXAMPLE_AMI_ID,
|
||||||
|
"InstanceType": "t3.small",
|
||||||
|
"UserData": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"AutoScalingGroup": {
|
||||||
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
||||||
|
"Properties": {
|
||||||
|
"AutoScalingGroupName": autoscaling_group_name,
|
||||||
|
"VPCZoneIdentifier": [subnet1.id],
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"LaunchTemplateId": {"Ref": "LaunchTemplate"},
|
||||||
|
"Version": {
|
||||||
|
"Fn::GetAtt": ["LaunchTemplate", version_attribute]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"MinSize": 1,
|
||||||
|
"MaxSize": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cf_client.create_stack(
|
||||||
|
StackName=stack_name,
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
||||||
|
OnFailure="DELETE",
|
||||||
|
)
|
||||||
|
|
||||||
|
template_json = json.dumps(
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "AWS CloudFormation Template to create an ASG group with LaunchTemplate",
|
||||||
|
"Resources": {
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"Type": "AWS::EC2::LaunchTemplate",
|
||||||
|
"Properties": {
|
||||||
|
"LaunchTemplateName": launch_template_name,
|
||||||
|
"LaunchTemplateData": {
|
||||||
|
"ImageId": EXAMPLE_AMI_ID2,
|
||||||
|
"InstanceType": "t3.medium",
|
||||||
|
"UserData": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"AutoScalingGroup": {
|
||||||
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
||||||
|
"Properties": {
|
||||||
|
"AutoScalingGroupName": autoscaling_group_name,
|
||||||
|
"VPCZoneIdentifier": [subnet2.id],
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"LaunchTemplateId": {"Ref": "LaunchTemplate"},
|
||||||
|
"Version": {
|
||||||
|
"Fn::GetAtt": ["LaunchTemplate", version_attribute]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"MinSize": 1,
|
||||||
|
"MaxSize": 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cf_client.update_stack(
|
||||||
|
StackName=stack_name,
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
||||||
|
)
|
||||||
|
|
||||||
|
autoscaling_group = autoscaling_client.describe_auto_scaling_groups(
|
||||||
|
AutoScalingGroupNames=[
|
||||||
|
autoscaling_group_name,
|
||||||
|
]
|
||||||
|
)["AutoScalingGroups"][0]
|
||||||
|
|
||||||
|
assert (
|
||||||
|
autoscaling_group["LaunchTemplate"]["LaunchTemplateName"]
|
||||||
|
== launch_template_name
|
||||||
|
)
|
||||||
|
assert autoscaling_group["LaunchTemplate"]["Version"] == "2"
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_cloudformation
|
||||||
|
@mock_ec2
|
||||||
|
def test_asg_with_default_launch_template_version():
|
||||||
|
cf_client = boto3.client("cloudformation", region_name="us-west-1")
|
||||||
|
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||||
|
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||||
|
autoscaling_client = boto3.client("autoscaling", region_name="us-west-1")
|
||||||
|
|
||||||
|
subnet1 = ec2.create_subnet(
|
||||||
|
CidrBlock="10.0.1.0/24", VpcId=vpc.id, AvailabilityZone="us-west-1a"
|
||||||
|
)
|
||||||
|
|
||||||
|
subnet2 = ec2.create_subnet(
|
||||||
|
CidrBlock="10.0.2.0/24", VpcId=vpc.id, AvailabilityZone="us-west-1b"
|
||||||
|
)
|
||||||
|
|
||||||
|
autoscaling_group_name = str(uuid4())
|
||||||
|
|
||||||
|
stack_name = str(uuid4())
|
||||||
|
launch_template_name = str(uuid4())[0:6]
|
||||||
|
|
||||||
|
version_attribute = "DefaultVersionNumber"
|
||||||
|
|
||||||
|
template_json = json.dumps(
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "AWS CloudFormation Template to create an ASG group with LaunchTemplate",
|
||||||
|
"Resources": {
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"Type": "AWS::EC2::LaunchTemplate",
|
||||||
|
"Properties": {
|
||||||
|
"LaunchTemplateName": launch_template_name,
|
||||||
|
"LaunchTemplateData": {
|
||||||
|
"ImageId": EXAMPLE_AMI_ID,
|
||||||
|
"InstanceType": "t3.small",
|
||||||
|
"UserData": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"AutoScalingGroup": {
|
||||||
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
||||||
|
"Properties": {
|
||||||
|
"AutoScalingGroupName": autoscaling_group_name,
|
||||||
|
"VPCZoneIdentifier": [subnet1.id],
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"LaunchTemplateId": {"Ref": "LaunchTemplate"},
|
||||||
|
"Version": {
|
||||||
|
"Fn::GetAtt": ["LaunchTemplate", version_attribute]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"MinSize": 1,
|
||||||
|
"MaxSize": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cf_client.create_stack(
|
||||||
|
StackName=stack_name,
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
||||||
|
OnFailure="DELETE",
|
||||||
|
)
|
||||||
|
|
||||||
|
template_json = json.dumps(
|
||||||
|
{
|
||||||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
|
"Description": "AWS CloudFormation Template to create an ASG group with LaunchTemplate",
|
||||||
|
"Resources": {
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"Type": "AWS::EC2::LaunchTemplate",
|
||||||
|
"Properties": {
|
||||||
|
"LaunchTemplateName": launch_template_name,
|
||||||
|
"LaunchTemplateData": {
|
||||||
|
"ImageId": EXAMPLE_AMI_ID2,
|
||||||
|
"InstanceType": "t3.medium",
|
||||||
|
"UserData": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"AutoScalingGroup": {
|
||||||
|
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
||||||
|
"Properties": {
|
||||||
|
"AutoScalingGroupName": autoscaling_group_name,
|
||||||
|
"VPCZoneIdentifier": [subnet2.id],
|
||||||
|
"LaunchTemplate": {
|
||||||
|
"LaunchTemplateId": {"Ref": "LaunchTemplate"},
|
||||||
|
"Version": {
|
||||||
|
"Fn::GetAtt": ["LaunchTemplate", version_attribute]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"MinSize": 1,
|
||||||
|
"MaxSize": 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cf_client.update_stack(
|
||||||
|
StackName=stack_name,
|
||||||
|
TemplateBody=template_json,
|
||||||
|
Capabilities=["CAPABILITY_NAMED_IAM"],
|
||||||
|
)
|
||||||
|
|
||||||
|
autoscaling_group = autoscaling_client.describe_auto_scaling_groups(
|
||||||
|
AutoScalingGroupNames=[
|
||||||
|
autoscaling_group_name,
|
||||||
|
]
|
||||||
|
)["AutoScalingGroups"][0]
|
||||||
|
|
||||||
|
assert (
|
||||||
|
autoscaling_group["LaunchTemplate"]["LaunchTemplateName"]
|
||||||
|
== launch_template_name
|
||||||
|
)
|
||||||
|
assert autoscaling_group["LaunchTemplate"]["Version"] == "1"
|
Loading…
Reference in New Issue
Block a user