2021-10-04 13:47:40 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2020-09-13 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00: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"}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
def test_delete_stack_with_resource_missing_delete_attr():
|
|
|
|
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))
|
|
|
|
cf.describe_stacks(StackName=name)["Stacks"].should.have.length_of(1)
|
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
|
|
|
|
|
|
|
cf.delete_stack(
|
|
|
|
StackName=name
|
|
|
|
) # should succeed, despite the fact that the resource itself cannot be deleted
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
cf.describe_stacks(StackName=name)
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
err.should.have.key("Code").equals("ValidationError")
|
2021-10-05 17:11:07 +00:00
|
|
|
err.should.have.key("Message").equals(f"Stack with id {name} does not exist")
|
2021-10-04 13:47:40 +00:00
|
|
|
|
2021-10-05 17:11:07 +00:00
|
|
|
# We still have our VPC, as the VPC-object does not have a delete-method yet
|
|
|
|
ec2.describe_vpcs(VpcIds=[vpc_id])["Vpcs"].should.have.length_of(1)
|
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 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00: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 15:08:23 +00:00
|
|
|
|
2021-10-10 21:43:49 +00:00
|
|
|
volume_template = {
|
2020-09-13 15:08:23 +00: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 15:08:23 +00:00
|
|
|
"Properties": {
|
2021-10-10 21:43:49 +00:00
|
|
|
"VpcId": {"Ref": "DEVLAB1"},
|
|
|
|
"InternetGatewayId": {"Ref": "internetgateway"},
|
2020-09-13 15:08:23 +00:00
|
|
|
},
|
2021-10-10 21:43:49 +00:00
|
|
|
},
|
2020-09-13 15:08:23 +00: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 14:39:59 +00: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 15:08:23 +00: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 22:43:25 +00: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-04-27 11:58:59 +00:00
|
|
|
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-1a"
|
2022-03-03 22:43:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
subnet_template = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Parameters": {
|
2022-03-10 14:39:59 +00:00
|
|
|
"EndpointSubnetId": {"Type": "String"},
|
|
|
|
"EndpointVpcId": {"Type": "String"},
|
|
|
|
"EndpointServiceName": {"Type": "String"},
|
2022-03-03 22:43:25 +00: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")
|