| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | from botocore.exceptions import ClientError | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | from moto import mock_cloudformation, mock_ec2 | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  | from tests import EXAMPLE_AMI_ID | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | from tests.test_cloudformation.fixtures import ec2_classic_eip | 
					
						
							|  |  |  | from tests.test_cloudformation.fixtures import single_instance_with_ebs_volume | 
					
						
							|  |  |  | from tests.test_cloudformation.fixtures import vpc_eip | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | from tests.test_cloudformation.fixtures import vpc_eni | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | from tests.test_cloudformation.fixtures import vpc_single_instance_in_subnet | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | from uuid import uuid4 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | import boto3 | 
					
						
							|  |  |  | import json | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | template_vpc = { | 
					
						
							|  |  |  |     "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |     "Description": "Create VPC", | 
					
						
							|  |  |  |     "Resources": { | 
					
						
							|  |  |  |         "VPC": {"Properties": {"CidrBlock": "192.168.0.0/16"}, "Type": "AWS::EC2::VPC"} | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 12:49:03 -05:00
										 |  |  | template_subnet = { | 
					
						
							|  |  |  |     "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |     "Description": "Create VPC", | 
					
						
							|  |  |  |     "Resources": { | 
					
						
							|  |  |  |         "VPC": {"Properties": {"CidrBlock": "192.168.0.0/16"}, "Type": "AWS::EC2::VPC"}, | 
					
						
							|  |  |  |         "Subnet": { | 
					
						
							|  |  |  |             "Properties": {"VpcId": {"Ref": "VPC"}, "CidrBlock": "192.168.0.0/18"}, | 
					
						
							|  |  |  |             "Type": "AWS::EC2::Subnet", | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_vpc_single_instance_in_subnet(): | 
					
						
							|  |  |  |     template_json = json.dumps(vpc_single_instance_in_subnet.template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cf.create_stack( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         StackName=stack_name, | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         TemplateBody=template_json, | 
					
						
							|  |  |  |         Parameters=[{"ParameterKey": "KeyName", "ParameterValue": "my_key"}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack = cf.describe_stacks(StackName=stack_name)["Stacks"][0] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     vpc_id = [ | 
					
						
							|  |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::VPC" | 
					
						
							|  |  |  |     ][0]["PhysicalResourceId"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     vpc = ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"][0] | 
					
						
							|  |  |  |     vpc["CidrBlock"].should.equal("10.0.0.0/16") | 
					
						
							|  |  |  |     vpc["Tags"].should.contain({"Key": "Application", "Value": stack["StackId"]}) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     security_group = ec2.describe_security_groups( | 
					
						
							|  |  |  |         Filters=[{"Name": "vpc-id", "Values": [vpc["VpcId"]]}] | 
					
						
							|  |  |  |     )["SecurityGroups"][0] | 
					
						
							|  |  |  |     security_group["VpcId"].should.equal(vpc["VpcId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     subnet_id = [ | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         if resource["ResourceType"] == "AWS::EC2::Subnet" | 
					
						
							|  |  |  |     ][0]["PhysicalResourceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subnet = ec2.describe_subnets(SubnetIds=[subnet_id])["Subnets"][0] | 
					
						
							|  |  |  |     subnet["VpcId"].should.equal(vpc["VpcId"]) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_id = [ | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         if resource["ResourceType"] == "AWS::EC2::Instance" | 
					
						
							|  |  |  |     ][0]["PhysicalResourceId"] | 
					
						
							|  |  |  |     res = ec2.describe_instances(InstanceIds=[instance_id])["Reservations"][0] | 
					
						
							|  |  |  |     instance = res["Instances"][0] | 
					
						
							|  |  |  |     instance["Tags"].should.contain({"Key": "Foo", "Value": "Bar"}) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     eip_id = [ | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::EIP" | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     ][0]["PhysicalResourceId"] | 
					
						
							|  |  |  |     eip = ec2.describe_addresses(PublicIps=[eip_id])["Addresses"][0] | 
					
						
							|  |  |  |     eip["Domain"].should.equal("vpc") | 
					
						
							|  |  |  |     eip["InstanceId"].should.equal(instance["InstanceId"]) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2023-03-24 12:49:03 -05:00
										 |  |  | def test_delete_stack_with_vpc(): | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cf = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     name = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     cf.create_stack(StackName=name, TemplateBody=json.dumps(template_vpc)) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     vpc_id = resources[0]["PhysicalResourceId"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"].should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 12:49:03 -05:00
										 |  |  |     cf.delete_stack(StackName=name) | 
					
						
							|  |  |  |     with pytest.raises(ec2.exceptions.ClientError): | 
					
						
							|  |  |  |         ec2.describe_vpcs(VpcIds=[vpc_id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_delete_stack_with_subnet(): | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     name = str(uuid4())[0:6] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.create_stack(StackName=name, TemplateBody=json.dumps(template_subnet)) | 
					
						
							|  |  |  |     subnet_ids = [ | 
					
						
							|  |  |  |         resource["PhysicalResourceId"] | 
					
						
							|  |  |  |         for resource in cf.list_stack_resources(StackName=name)[ | 
					
						
							|  |  |  |             "StackResourceSummaries" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::Subnet" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ec2.describe_subnets(SubnetIds=subnet_ids)["Subnets"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.delete_stack(StackName=name) | 
					
						
							|  |  |  |     with pytest.raises(ec2.exceptions.ClientError): | 
					
						
							|  |  |  |         ec2.describe_subnets(SubnetIds=subnet_ids) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_elastic_network_interfaces_cloudformation_boto3(): | 
					
						
							|  |  |  |     template = vpc_eni.template | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_enis = ec2.describe_network_interfaces()["NetworkInterfaces"] | 
					
						
							|  |  |  |     all_eni_ids = [eni["NetworkInterfaceId"] for eni in all_enis] | 
					
						
							|  |  |  |     all_ips = [eni["PrivateIpAddresses"][0]["PrivateIpAddress"] for eni in all_enis] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cfn_eni = [ | 
					
						
							|  |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::NetworkInterface" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_eni_ids.should.contain(cfn_eni["PhysicalResourceId"]) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     outputs = cf.describe_stacks(StackName=stack_name)["Stacks"][0]["Outputs"] | 
					
						
							|  |  |  |     received_ip = [ | 
					
						
							|  |  |  |         o["OutputValue"] for o in outputs if o["OutputKey"] == "ENIIpAddress" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  |     all_ips.should.contain(received_ip) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_volume_size_through_cloudformation(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     tag_value = str(uuid4()) | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |     volume_template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "testInstance": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::Instance", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |                     "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |                     "KeyName": "dummy", | 
					
						
							|  |  |  |                     "InstanceType": "t2.micro", | 
					
						
							|  |  |  |                     "BlockDeviceMappings": [ | 
					
						
							|  |  |  |                         {"DeviceName": "/dev/sda2", "Ebs": {"VolumeSize": "50"}} | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                     "Tags": [ | 
					
						
							|  |  |  |                         {"Key": "foo", "Value": "bar"}, | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                         {"Key": "blah", "Value": tag_value}, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     template_json = json.dumps(volume_template) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resource = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"][ | 
					
						
							|  |  |  |         0 | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     resource.should.have.key("LogicalResourceId").being.equal("testInstance") | 
					
						
							|  |  |  |     resource.should.have.key("PhysicalResourceId").shouldnt.be.none | 
					
						
							|  |  |  |     resource.should.have.key("ResourceType").being.equal("AWS::EC2::Instance") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instances = ec2.describe_instances(InstanceIds=[resource["PhysicalResourceId"]]) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |     volume = instances["Reservations"][0]["Instances"][0]["BlockDeviceMappings"][0][ | 
					
						
							|  |  |  |         "Ebs" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volumes = ec2.describe_volumes(VolumeIds=[volume["VolumeId"]]) | 
					
						
							|  |  |  |     volumes["Volumes"][0]["Size"].should.equal(50) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_attach_internet_gateway(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |     volume_template = { | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |             "DEVLAB1": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPC", | 
					
						
							|  |  |  |                 "Properties": {"CidrBlock": "10.0.0.0/16"}, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "internetgateway": {"Type": "AWS::EC2::InternetGateway"}, | 
					
						
							|  |  |  |             "DEVLAB1VPGAttaching": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPCGatewayAttachment", | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |                 "Properties": { | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |                     "VpcId": {"Ref": "DEVLAB1"}, | 
					
						
							|  |  |  |                     "InternetGatewayId": {"Ref": "internetgateway"}, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |             }, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |     template_json = json.dumps(volume_template) | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     stack_resources = cf.list_stack_resources(StackName=stack_name)[ | 
					
						
							|  |  |  |         "StackResourceSummaries" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify VPC is created | 
					
						
							|  |  |  |     vpc = [r for r in stack_resources if r["ResourceType"] == "AWS::EC2::VPC"][0] | 
					
						
							|  |  |  |     vpc["LogicalResourceId"].should.equal("DEVLAB1") | 
					
						
							|  |  |  |     vpc_id = vpc["PhysicalResourceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify Internet Gateway is created | 
					
						
							|  |  |  |     gateway_id = get_resource_id("AWS::EC2::InternetGateway", stack_resources) | 
					
						
							|  |  |  |     gateway = ec2.describe_internet_gateways(InternetGatewayIds=[gateway_id])[ | 
					
						
							|  |  |  |         "InternetGateways" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  |     gateway["Attachments"].should.contain({"State": "available", "VpcId": vpc_id}) | 
					
						
							|  |  |  |     gateway["Tags"].should.contain( | 
					
						
							|  |  |  |         {"Key": "aws:cloudformation:logical-id", "Value": "internetgateway"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_attach_vpn_gateway(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vpn_gateway_template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "DEVLAB1": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPC", | 
					
						
							|  |  |  |                 "Properties": {"CidrBlock": "10.0.0.0/16"}, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "DEVLAB1DCGateway": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPNGateway", | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                 "Properties": {"Type": "ipsec.1"}, | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  |             }, | 
					
						
							|  |  |  |             "DEVLAB1VPGAttaching": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPCGatewayAttachment", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "VpcId": {"Ref": "DEVLAB1"}, | 
					
						
							|  |  |  |                     "VpnGatewayId": {"Ref": "DEVLAB1DCGateway"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "DependsOn": ["DEVLAB1DCGateway"], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     template_json = json.dumps(vpn_gateway_template) | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     stack_resources = cf.list_stack_resources(StackName=stack_name)[ | 
					
						
							|  |  |  |         "StackResourceSummaries" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gateway_id = get_resource_id("AWS::EC2::VPNGateway", stack_resources) | 
					
						
							|  |  |  |     vpc_id = get_resource_id("AWS::EC2::VPC", stack_resources) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gateway = ec2.describe_vpn_gateways(VpnGatewayIds=[gateway_id])["VpnGateways"][0] | 
					
						
							|  |  |  |     gateway["VpcAttachments"].should.contain({"State": "attached", "VpcId": vpc_id}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 21:43:49 +00:00
										 |  |  | def get_resource_id(resource_type, stack_resources): | 
					
						
							|  |  |  |     r = [r for r in stack_resources if r["ResourceType"] == resource_type][0] | 
					
						
							|  |  |  |     return r["PhysicalResourceId"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_subnet_tags_through_cloudformation_boto3(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_res = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc = ec2_res.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subnet_template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "testSubnet": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::Subnet", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "VpcId": vpc.id, | 
					
						
							|  |  |  |                     "CidrBlock": "10.0.0.0/24", | 
					
						
							|  |  |  |                     "AvailabilityZone": "us-west-1b", | 
					
						
							|  |  |  |                     "Tags": [ | 
					
						
							|  |  |  |                         {"Key": "foo", "Value": "bar"}, | 
					
						
							|  |  |  |                         {"Key": "blah", "Value": "baz"}, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     template_json = json.dumps(subnet_template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     subnet_id = resources[0]["PhysicalResourceId"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     subnet = ec2.describe_subnets(SubnetIds=[subnet_id])["Subnets"][0] | 
					
						
							|  |  |  |     subnet["CidrBlock"].should.equal("10.0.0.0/24") | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     subnet["Tags"].should.contain({"Key": "foo", "Value": "bar"}) | 
					
						
							|  |  |  |     subnet["Tags"].should.contain({"Key": "blah", "Value": "baz"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_single_instance_with_ebs_volume(): | 
					
						
							|  |  |  |     template_json = json.dumps(single_instance_with_ebs_volume.template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cf.create_stack( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         StackName=stack_name, | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         TemplateBody=template_json, | 
					
						
							|  |  |  |         Parameters=[{"ParameterKey": "KeyName", "ParameterValue": "key_name"}], | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     instance_id = [ | 
					
						
							|  |  |  |         r["PhysicalResourceId"] | 
					
						
							|  |  |  |         for r in resources | 
					
						
							|  |  |  |         if r["ResourceType"] == "AWS::EC2::Instance" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  |     volume_id = [ | 
					
						
							|  |  |  |         r["PhysicalResourceId"] | 
					
						
							|  |  |  |         for r in resources | 
					
						
							|  |  |  |         if r["ResourceType"] == "AWS::EC2::Volume" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     ec2_instance = ec2.describe_instances(InstanceIds=[instance_id])["Reservations"][0][ | 
					
						
							|  |  |  |         "Instances" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     volumes = ec2.describe_volumes(VolumeIds=[volume_id])["Volumes"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     # Grab the mounted drive | 
					
						
							|  |  |  |     volume = [ | 
					
						
							|  |  |  |         volume for volume in volumes if volume["Attachments"][0]["Device"] == "/dev/sdh" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  |     volume["State"].should.equal("in-use") | 
					
						
							|  |  |  |     volume["Attachments"][0]["InstanceId"].should.equal(ec2_instance["InstanceId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_classic_eip(): | 
					
						
							|  |  |  |     template_json = json.dumps(ec2_classic_eip.template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_ips = [eip["PublicIp"] for eip in ec2.describe_addresses()["Addresses"]] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cfn_eip = [ | 
					
						
							|  |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::EIP" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_ips.should.contain(cfn_eip["PhysicalResourceId"]) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_vpc_eip(): | 
					
						
							|  |  |  |     template_json = json.dumps(vpc_eip.template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_ips = [eip["PublicIp"] for eip in ec2.describe_addresses()["Addresses"]] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     cfn_eip = [ | 
					
						
							|  |  |  |         resource | 
					
						
							|  |  |  |         for resource in resources | 
					
						
							|  |  |  |         if resource["ResourceType"] == "AWS::EC2::EIP" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_ips.should.contain(cfn_eip["PhysicalResourceId"]) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_vpc_gateway_attachment_creation_should_attach_itself_to_vpc(): | 
					
						
							|  |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "internetgateway": {"Type": "AWS::EC2::InternetGateway"}, | 
					
						
							|  |  |  |             "testvpc": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPC", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "CidrBlock": "10.0.0.0/16", | 
					
						
							|  |  |  |                     "EnableDnsHostnames": "true", | 
					
						
							|  |  |  |                     "EnableDnsSupport": "true", | 
					
						
							|  |  |  |                     "InstanceTenancy": "default", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "vpcgatewayattachment": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPCGatewayAttachment", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "InternetGatewayId": {"Ref": "internetgateway"}, | 
					
						
							|  |  |  |                     "VpcId": {"Ref": "testvpc"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     vpc_id = resources[1]["PhysicalResourceId"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     vpc = ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"][0] | 
					
						
							|  |  |  |     vpc["CidrBlock"].should.equal("10.0.0.0/16") | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     igws = ec2.describe_internet_gateways( | 
					
						
							|  |  |  |         Filters=[{"Name": "attachment.vpc-id", "Values": [vpc["VpcId"]]}] | 
					
						
							|  |  |  |     )["InternetGateways"] | 
					
						
							|  |  |  |     igws.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_vpc_peering_creation(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc_source = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     peer_vpc = ec2.create_vpc(CidrBlock="10.1.0.0/16") | 
					
						
							|  |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "vpcpeeringconnection": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPCPeeringConnection", | 
					
						
							|  |  |  |                 "Properties": {"PeerVpcId": peer_vpc.id, "VpcId": vpc_source.id}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     our_vpx_id = resources[0]["PhysicalResourceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peering_connections = ec2_client.describe_vpc_peering_connections( | 
					
						
							|  |  |  |         VpcPeeringConnectionIds=[our_vpx_id] | 
					
						
							|  |  |  |     )["VpcPeeringConnections"] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     peering_connections.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_multiple_security_group_ingress_separate_from_security_group_by_id(): | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sg1 = str(uuid4())[0:6] | 
					
						
							|  |  |  |     sg2 = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "test-security-group1": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                     "Tags": [{"Key": "sg-name", "Value": sg1}], | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "test-security-group2": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                     "Tags": [{"Key": "sg-name", "Value": sg2}], | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "test-sg-ingress": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroupIngress", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupId": {"Ref": "test-security-group1"}, | 
					
						
							|  |  |  |                     "IpProtocol": "tcp", | 
					
						
							|  |  |  |                     "FromPort": "80", | 
					
						
							|  |  |  |                     "ToPort": "8080", | 
					
						
							|  |  |  |                     "SourceSecurityGroupId": {"Ref": "test-security-group2"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     cf.create_stack(StackName=str(uuid4())[0:6], TemplateBody=template_json) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     security_group1 = get_secgroup_by_tag(ec2, sg1) | 
					
						
							|  |  |  |     security_group2 = get_secgroup_by_tag(ec2, sg2) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     security_group1["IpPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"][0]["GroupId"].should.equal( | 
					
						
							|  |  |  |         security_group2["GroupId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["IpProtocol"].should.equal("tcp") | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["FromPort"].should.equal(80) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["ToPort"].should.equal(8080) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_security_group_ingress_separate_from_security_group_by_id(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sg_name = str(uuid4()) | 
					
						
							|  |  |  |     ec2.create_security_group(GroupName=sg_name, Description="test security group") | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sg_2 = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "test-security-group2": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                     "Tags": [{"Key": "sg-name", "Value": sg_2}], | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "test-sg-ingress": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroupIngress", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                     "GroupName": sg_name, | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |                     "IpProtocol": "tcp", | 
					
						
							|  |  |  |                     "FromPort": "80", | 
					
						
							|  |  |  |                     "ToPort": "8080", | 
					
						
							|  |  |  |                     "SourceSecurityGroupId": {"Ref": "test-security-group2"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     cf.create_stack(StackName=str(uuid4())[0:6], TemplateBody=template_json) | 
					
						
							|  |  |  |     security_group1 = ec2.describe_security_groups(GroupNames=[sg_name])[ | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |         "SecurityGroups" | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     security_group2 = get_secgroup_by_tag(ec2, sg_2) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     security_group1["IpPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"][0]["GroupId"].should.equal( | 
					
						
							|  |  |  |         security_group2["GroupId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["IpProtocol"].should.equal("tcp") | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["FromPort"].should.equal(80) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["ToPort"].should.equal(8080) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_security_group_ingress_separate_from_security_group_by_id_using_vpc(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "test-security-group1": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							|  |  |  |                     "VpcId": vpc.id, | 
					
						
							|  |  |  |                     "Tags": [{"Key": "sg-name", "Value": "sg1"}], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "test-security-group2": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							|  |  |  |                     "VpcId": vpc.id, | 
					
						
							|  |  |  |                     "Tags": [{"Key": "sg-name", "Value": "sg2"}], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "test-sg-ingress": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroupIngress", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupId": {"Ref": "test-security-group1"}, | 
					
						
							|  |  |  |                     "VpcId": vpc.id, | 
					
						
							|  |  |  |                     "IpProtocol": "tcp", | 
					
						
							|  |  |  |                     "FromPort": "80", | 
					
						
							|  |  |  |                     "ToPort": "8080", | 
					
						
							|  |  |  |                     "SourceSecurityGroupId": {"Ref": "test-security-group2"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     cf.create_stack(StackName=str(uuid4())[0:6], TemplateBody=template_json) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     security_group1 = get_secgroup_by_tag(ec2_client, "sg1") | 
					
						
							|  |  |  |     security_group2 = get_secgroup_by_tag(ec2_client, "sg2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     security_group1["IpPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"].should.have.length_of(1) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["UserIdGroupPairs"][0]["GroupId"].should.equal( | 
					
						
							|  |  |  |         security_group2["GroupId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["IpProtocol"].should.equal("tcp") | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["FromPort"].should.equal(80) | 
					
						
							|  |  |  |     security_group1["IpPermissions"][0]["ToPort"].should.equal(8080) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_security_group_with_update(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     vpc2 = ec2.create_vpc(CidrBlock="10.1.0.0/16") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sg = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "test-security-group": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::SecurityGroup", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "GroupDescription": "test security group", | 
					
						
							|  |  |  |                     "VpcId": vpc1.id, | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |                     "Tags": [{"Key": "sg-name", "Value": sg}], | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     security_group = get_secgroup_by_tag(ec2_client, sg) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     security_group["VpcId"].should.equal(vpc1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template["Resources"]["test-security-group"]["Properties"]["VpcId"] = vpc2.id | 
					
						
							|  |  |  |     template_json = json.dumps(template) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     cf.update_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     security_group = get_secgroup_by_tag(ec2_client, sg) | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     security_group["VpcId"].should.equal(vpc2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_subnets_should_be_created_with_availability_zone(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subnet_template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "testSubnet": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::Subnet", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "VpcId": vpc.id, | 
					
						
							|  |  |  |                     "CidrBlock": "10.0.0.0/24", | 
					
						
							|  |  |  |                     "AvailabilityZone": "us-west-1b", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							|  |  |  |     template_json = json.dumps(subnet_template) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     subnet_id = resources[0]["PhysicalResourceId"] | 
					
						
							|  |  |  |     subnet = ec2_client.describe_subnets(SubnetIds=[subnet_id])["Subnets"][0] | 
					
						
							|  |  |  |     subnet["CidrBlock"].should.equal("10.0.0.0/24") | 
					
						
							| 
									
										
										
										
											2021-10-04 13:47:40 +00:00
										 |  |  |     subnet["AvailabilityZone"].should.equal("us-west-1b") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_secgroup_by_tag(ec2, sg_): | 
					
						
							|  |  |  |     return ec2.describe_security_groups( | 
					
						
							|  |  |  |         Filters=[{"Name": "tag:sg-name", "Values": [sg_]}] | 
					
						
							|  |  |  |     )["SecurityGroups"][0] | 
					
						
							| 
									
										
										
										
											2022-03-03 21:43:25 -01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_vpc_endpoint_creation(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet1 = ec2.create_subnet( | 
					
						
							| 
									
										
										
										
											2022-10-02 13:03:03 +00:00
										 |  |  |         VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a" | 
					
						
							| 
									
										
										
										
											2022-03-03 21:43:25 -01:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subnet_template = { | 
					
						
							|  |  |  |         "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |         "Parameters": { | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             "EndpointSubnetId": {"Type": "String"}, | 
					
						
							|  |  |  |             "EndpointVpcId": {"Type": "String"}, | 
					
						
							|  |  |  |             "EndpointServiceName": {"Type": "String"}, | 
					
						
							| 
									
										
										
										
											2022-03-03 21:43:25 -01:00
										 |  |  |         }, | 
					
						
							|  |  |  |         "Resources": { | 
					
						
							|  |  |  |             "GwlbVpcEndpoint": { | 
					
						
							|  |  |  |                 "Type": "AWS::EC2::VPCEndpoint", | 
					
						
							|  |  |  |                 "Properties": { | 
					
						
							|  |  |  |                     "ServiceName": {"Ref": "EndpointServiceName"}, | 
					
						
							|  |  |  |                     "SubnetIds": [{"Ref": "EndpointSubnetId"}], | 
					
						
							|  |  |  |                     "VpcEndpointType": "GatewayLoadBalancer", | 
					
						
							|  |  |  |                     "VpcId": {"Ref": "EndpointVpcId"}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         "Outputs": { | 
					
						
							|  |  |  |             "EndpointId": { | 
					
						
							|  |  |  |                 "Description": "Id of the endpoint created", | 
					
						
							|  |  |  |                 "Value": {"Ref": "GwlbVpcEndpoint"}, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							|  |  |  |     template_json = json.dumps(subnet_template) | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     cf.create_stack( | 
					
						
							|  |  |  |         StackName=stack_name, | 
					
						
							|  |  |  |         TemplateBody=template_json, | 
					
						
							|  |  |  |         Parameters=[ | 
					
						
							|  |  |  |             {"ParameterKey": "EndpointSubnetId", "ParameterValue": subnet1.id}, | 
					
						
							|  |  |  |             {"ParameterKey": "EndpointVpcId", "ParameterValue": vpc.id}, | 
					
						
							|  |  |  |             {"ParameterKey": "EndpointServiceName", "ParameterValue": "serv_name"}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     resources.should.have.length_of(1) | 
					
						
							|  |  |  |     resources[0].should.have.key("LogicalResourceId").equals("GwlbVpcEndpoint") | 
					
						
							|  |  |  |     vpc_endpoint_id = resources[0]["PhysicalResourceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     outputs = cf.describe_stacks(StackName=stack_name)["Stacks"][0]["Outputs"] | 
					
						
							|  |  |  |     outputs.should.have.length_of(1) | 
					
						
							|  |  |  |     outputs[0].should.equal({"OutputKey": "EndpointId", "OutputValue": vpc_endpoint_id}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     endpoint = ec2_client.describe_vpc_endpoints(VpcEndpointIds=[vpc_endpoint_id])[ | 
					
						
							|  |  |  |         "VpcEndpoints" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  |     endpoint.should.have.key("VpcId").equals(vpc.id) | 
					
						
							|  |  |  |     endpoint.should.have.key("ServiceName").equals("serv_name") | 
					
						
							|  |  |  |     endpoint.should.have.key("State").equals("available") | 
					
						
							|  |  |  |     endpoint.should.have.key("SubnetIds").equals([subnet1.id]) | 
					
						
							|  |  |  |     endpoint.should.have.key("VpcEndpointType").equals("GatewayLoadBalancer") | 
					
						
							| 
									
										
										
										
											2022-09-16 06:01:43 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_launch_template_create(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     logical_id = str(uuid4())[0:6] | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lt_tags = [{"Key": "lt-tag-key", "Value": "lt-tag-value"}] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |             "Resources": { | 
					
						
							|  |  |  |                 logical_id: { | 
					
						
							|  |  |  |                     "Type": "AWS::EC2::LaunchTemplate", | 
					
						
							|  |  |  |                     "Properties": { | 
					
						
							|  |  |  |                         "LaunchTemplateName": launch_template_name, | 
					
						
							|  |  |  |                         "VersionDescription": "some template", | 
					
						
							|  |  |  |                         "LaunchTemplateData": { | 
					
						
							|  |  |  |                             "TagSpecifications": [ | 
					
						
							|  |  |  |                                 { | 
					
						
							|  |  |  |                                     "ResourceType": "instance", | 
					
						
							|  |  |  |                                     "Tags": [ | 
					
						
							|  |  |  |                                         {"Key": "i-tag-key", "Value": "i-tag-value"} | 
					
						
							|  |  |  |                                     ], | 
					
						
							|  |  |  |                                 } | 
					
						
							|  |  |  |                             ] | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                         "TagSpecifications": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "ResourceType": "launch-template", | 
					
						
							|  |  |  |                                 "Tags": lt_tags, | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Outputs": { | 
					
						
							|  |  |  |                 "LaunchTemplateId": { | 
					
						
							|  |  |  |                     "Description": "The ID of the created launch template", | 
					
						
							|  |  |  |                     "Value": {"Ref": logical_id}, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     resources.should.have.length_of(1) | 
					
						
							|  |  |  |     resources[0].should.have.key("LogicalResourceId").equals(logical_id) | 
					
						
							|  |  |  |     launch_template_id = resources[0]["PhysicalResourceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     outputs = cf.describe_stacks(StackName=stack_name)["Stacks"][0]["Outputs"] | 
					
						
							|  |  |  |     outputs.should.have.length_of(1) | 
					
						
							|  |  |  |     outputs[0].should.equal( | 
					
						
							|  |  |  |         {"OutputKey": "LaunchTemplateId", "OutputValue": launch_template_id} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template = ec2.describe_launch_templates( | 
					
						
							|  |  |  |         LaunchTemplateNames=[launch_template_name] | 
					
						
							|  |  |  |     )["LaunchTemplates"][0] | 
					
						
							|  |  |  |     launch_template.should.have.key("LaunchTemplateName").equals(launch_template_name) | 
					
						
							|  |  |  |     launch_template.should.have.key("LaunchTemplateId").equals(launch_template_id) | 
					
						
							|  |  |  |     launch_template.should.have.key("Tags").equals(lt_tags) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template_version = ec2.describe_launch_template_versions( | 
					
						
							|  |  |  |         LaunchTemplateName=launch_template_name | 
					
						
							|  |  |  |     )["LaunchTemplateVersions"][0] | 
					
						
							|  |  |  |     launch_template_version.should.have.key("LaunchTemplateName").equals( | 
					
						
							|  |  |  |         launch_template_name | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     launch_template_version.should.have.key("LaunchTemplateId").equals( | 
					
						
							|  |  |  |         launch_template_id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     launch_template_version["LaunchTemplateData"]["TagSpecifications"][ | 
					
						
							|  |  |  |         0 | 
					
						
							|  |  |  |     ].should.have.key("ResourceType").equals("instance") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_launch_template_update(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     logical_id = str(uuid4())[0:6] | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |             "Resources": { | 
					
						
							|  |  |  |                 logical_id: { | 
					
						
							|  |  |  |                     "Type": "AWS::EC2::LaunchTemplate", | 
					
						
							|  |  |  |                     "Properties": { | 
					
						
							|  |  |  |                         "LaunchTemplateName": launch_template_name, | 
					
						
							|  |  |  |                         "VersionDescription": "some template", | 
					
						
							|  |  |  |                         "LaunchTemplateData": {"UserData": ""}, | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |             "Resources": { | 
					
						
							|  |  |  |                 logical_id: { | 
					
						
							|  |  |  |                     "Type": "AWS::EC2::LaunchTemplate", | 
					
						
							|  |  |  |                     "Properties": { | 
					
						
							|  |  |  |                         "LaunchTemplateName": launch_template_name, | 
					
						
							|  |  |  |                         "VersionDescription": "a better template", | 
					
						
							|  |  |  |                         "LaunchTemplateData": {"UserData": ""}, | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.update_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resources = cf.list_stack_resources(StackName=stack_name)["StackResourceSummaries"] | 
					
						
							|  |  |  |     resources.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template_versions = ec2.describe_launch_template_versions( | 
					
						
							|  |  |  |         LaunchTemplateName=launch_template_name | 
					
						
							|  |  |  |     )["LaunchTemplateVersions"] | 
					
						
							|  |  |  |     launch_template_versions.should.have.length_of(2) | 
					
						
							|  |  |  |     launch_template_versions[0].should.have.key("VersionDescription").equals( | 
					
						
							|  |  |  |         "some template" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     launch_template_versions[1].should.have.key("VersionDescription").equals( | 
					
						
							|  |  |  |         "a better template" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_launch_template_delete(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf = boto3.client("cloudformation", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     launch_template_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     logical_id = str(uuid4())[0:6] | 
					
						
							|  |  |  |     stack_name = str(uuid4())[0:6] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template_json = json.dumps( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |             "Resources": { | 
					
						
							|  |  |  |                 logical_id: { | 
					
						
							|  |  |  |                     "Type": "AWS::EC2::LaunchTemplate", | 
					
						
							|  |  |  |                     "Properties": { | 
					
						
							|  |  |  |                         "LaunchTemplateName": launch_template_name, | 
					
						
							|  |  |  |                         "VersionDescription": "some template", | 
					
						
							|  |  |  |                         "LaunchTemplateData": {"UserData": ""}, | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     cf.create_stack(StackName=stack_name, TemplateBody=template_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf.delete_stack(StackName=stack_name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 18:47:06 +05:30
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         ec2.describe_launch_templates(LaunchTemplateNames=[launch_template_name]) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     err.should.have.key("Code").equals("InvalidLaunchTemplateName.NotFoundException") | 
					
						
							|  |  |  |     err.should.have.key("Message").equals( | 
					
						
							|  |  |  |         "At least one of the launch templates specified in the request does not exist." | 
					
						
							|  |  |  |     ) |