diff --git a/moto/ec2/models.py b/moto/ec2/models.py
index 4a9ba1460..27de681d0 100644
--- a/moto/ec2/models.py
+++ b/moto/ec2/models.py
@@ -136,7 +136,6 @@ from .utils import (
random_transit_gateway_attachment_id,
random_transit_gateway_route_table_id,
random_vpc_ep_id,
- randor_ipv4_cidr,
random_launch_template_id,
random_nat_gateway_id,
random_transit_gateway_id,
@@ -3746,8 +3745,8 @@ class VPCBackend(object):
# validates if vpc is present or not.
self.get_vpc(vpc_id)
+ destination_prefix_list_id = None
- service_destination_cidr = None
if type and type.lower() == "interface":
network_interface_ids = []
@@ -3760,10 +3759,10 @@ class VPCBackend(object):
else:
# considering gateway if type is not mentioned.
- service_destination_cidr = randor_ipv4_cidr()
+ for prefix_list in self.managed_prefix_lists.values():
+ if prefix_list.prefix_list_name == service_name:
+ destination_prefix_list_id = prefix_list.id
- for route_table_id in route_table_ids:
- self.create_route(route_table_id, service_destination_cidr)
if dns_entries:
dns_entries = [dns_entries]
@@ -3782,15 +3781,23 @@ class VPCBackend(object):
security_group_ids,
tags,
private_dns_enabled,
- service_destination_cidr,
+ destination_prefix_list_id,
)
self.vpc_end_points[vpc_endpoint_id] = vpc_end_point
+ if destination_prefix_list_id:
+ for route_table_id in route_table_ids:
+ self.create_route(
+ route_table_id,
+ None,
+ gateway_id=vpc_endpoint_id,
+ destination_prefix_list_id=destination_prefix_list_id,
+ )
+
return vpc_end_point
def delete_vpc_endpoints(self, vpce_ids=[]):
- vpce_ids
for vpce_id in vpce_ids:
vpc_endpoint = self.vpc_end_points.get(vpce_id, None)
if vpc_endpoint:
@@ -3800,7 +3807,7 @@ class VPCBackend(object):
else:
for route_table_id in vpc_endpoint.route_table_ids:
self.delete_route(
- route_table_id, vpc_endpoint.service_destination_cidr
+ route_table_id, vpc_endpoint.destination_prefix_list_id
)
vpc_endpoint.state = "deleted"
return True
@@ -3839,6 +3846,12 @@ class VPCBackend(object):
"availability_zones": availability_zones,
}
+ def get_vpc_end_point(self, vpc_end_point_id):
+ vpc_end_point = self.vpc_end_points.get(vpc_end_point_id)
+ if not vpc_end_point:
+ raise InvalidVpcEndPointIdError(vpc_end_point_id)
+ return vpc_end_point
+
class PeeringConnectionStatus(object):
def __init__(self, code="initiating-request", message=""):
@@ -4863,7 +4876,7 @@ class Route(CloudFormationModel):
route_table,
destination_cidr_block,
destination_ipv6_cidr_block,
- prefix_list=None,
+ destination_prefix_list=None,
local=False,
gateway=None,
instance=None,
@@ -4875,12 +4888,15 @@ class Route(CloudFormationModel):
carrier_gateway=None,
):
self.id = generate_route_id(
- route_table.id, destination_cidr_block, destination_ipv6_cidr_block
+ route_table.id,
+ destination_cidr_block,
+ destination_ipv6_cidr_block,
+ destination_prefix_list.id if destination_prefix_list else None,
)
self.route_table = route_table
self.destination_cidr_block = destination_cidr_block
self.destination_ipv6_cidr_block = destination_ipv6_cidr_block
- self.prefix_list = prefix_list
+ self.destination_prefix_list = destination_prefix_list
self.local = local
self.gateway = gateway
self.instance = instance
@@ -4951,7 +4967,7 @@ class VPCEndPoint(TaggedEC2Resource):
security_group_ids=None,
tags=None,
private_dns_enabled=None,
- service_destination_cidr=None,
+ destination_prefix_list_id=None,
):
self.ec2_backend = ec2_backend
self.id = id
@@ -4966,10 +4982,9 @@ class VPCEndPoint(TaggedEC2Resource):
self.client_token = client_token
self.security_group_ids = security_group_ids
self.private_dns_enabled = private_dns_enabled
- # self.created_at = utc_date_and_time()
self.dns_entries = dns_entries
self.add_tags(tags or {})
- self.service_destination_cidr = service_destination_cidr
+ self.destination_prefix_list_id = destination_prefix_list_id
@property
def owner_id(self):
@@ -5169,7 +5184,7 @@ class RouteBackend(object):
transit_gateway = None
egress_only_igw = None
interface = None
- prefix_list = None
+ destination_prefix_list = None
carrier_gateway = None
route_table = self.get_route_table(route_table_id)
@@ -5184,6 +5199,8 @@ class RouteBackend(object):
gateway = self.get_vpn_gateway(gateway_id)
elif EC2_RESOURCE_TO_PREFIX["internet-gateway"] in gateway_id:
gateway = self.get_internet_gateway(gateway_id)
+ elif EC2_RESOURCE_TO_PREFIX["vpc-endpoint"] in gateway_id:
+ gateway = self.get_vpc_end_point(gateway_id)
try:
if destination_cidr_block:
@@ -5198,7 +5215,9 @@ class RouteBackend(object):
if transit_gateway_id is not None:
transit_gateway = self.transit_gateways.get(transit_gateway_id)
if destination_prefix_list_id is not None:
- prefix_list = self.managed_prefix_lists.get(destination_prefix_list_id)
+ destination_prefix_list = self.managed_prefix_lists.get(
+ destination_prefix_list_id
+ )
if carrier_gateway_id is not None:
carrier_gateway = self.carrier_gateways.get(carrier_gateway_id)
@@ -5206,7 +5225,7 @@ class RouteBackend(object):
route_table,
destination_cidr_block,
destination_ipv6_cidr_block,
- prefix_list,
+ destination_prefix_list,
local=local,
gateway=gateway,
instance=self.get_instance(instance_id) if instance_id else None,
@@ -5283,12 +5302,18 @@ class RouteBackend(object):
return route_table.get(route_id)
def delete_route(
- self, route_table_id, destination_cidr_block, destination_ipv6_cidr_block=None
+ self,
+ route_table_id,
+ destination_cidr_block,
+ destination_ipv6_cidr_block=None,
+ destination_prefix_list_id=None,
):
cidr = destination_cidr_block
route_table = self.get_route_table(route_table_id)
if destination_ipv6_cidr_block:
cidr = destination_ipv6_cidr_block
+ if destination_prefix_list_id:
+ cidr = destination_prefix_list_id
route_id = generate_route_id(route_table_id, cidr)
deleted = route_table.routes.pop(route_id, None)
if not deleted:
diff --git a/moto/ec2/responses/route_tables.py b/moto/ec2/responses/route_tables.py
index 3409320b9..ce852f59c 100644
--- a/moto/ec2/responses/route_tables.py
+++ b/moto/ec2/responses/route_tables.py
@@ -59,8 +59,12 @@ class RouteTables(BaseResponse):
route_table_id = self._get_param("RouteTableId")
destination_cidr_block = self._get_param("DestinationCidrBlock")
destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock")
+ destination_prefix_list_id = self._get_param("DestinationPrefixListId")
self.ec2_backend.delete_route(
- route_table_id, destination_cidr_block, destination_ipv6_cidr_block
+ route_table_id,
+ destination_cidr_block,
+ destination_ipv6_cidr_block,
+ destination_prefix_list_id,
)
template = self.response_template(DELETE_ROUTE_RESPONSE)
return template.render()
@@ -151,9 +155,13 @@ CREATE_ROUTE_TABLE_RESPONSE = """
-
{% if route.destination_ipv6_cidr_block %}
{{ route.destination_ipv6_cidr_block }}
- {% else %}
+ {% endif %}
+ {% if route.destination_cidr_block %}
{{ route.destination_cidr_block }}
{% endif %}
+ {% if route.destination_prefix_list_id %}
+ {{ route.destination_prefix_list_id }}
+ {% endif %}
local
active
@@ -189,19 +197,18 @@ DESCRIBE_ROUTE_TABLES_RESPONSE = """
-
{% if route.destination_ipv6_cidr_block %}
{{ route.destination_ipv6_cidr_block }}
- {% else %}
- {{ route.destination_cidr_block or "" }}
+ {% endif %}
+ {% if route.destination_cidr_block %}
+ {{ route.destination_cidr_block }}
+ {% endif %}
+ {% if route.destination_prefix_list %}
+ {{ route.destination_prefix_list.id }}
{% endif %}
{% if route.local %}
local
CreateRouteTable
active
{% endif %}
- {% if route.prefix_list %}
- {{ route.prefix_list.id }}
- CreateRoute
- active
- {% endif %}
{% if route.gateway %}
{{ route.gateway.id }}
CreateRoute
@@ -215,27 +222,31 @@ DESCRIBE_ROUTE_TABLES_RESPONSE = """
{% if route.vpc_pcx %}
{{ route.vpc_pcx.id }}
CreateRoute
- blackhole
+ active
{% endif %}
{% if route.carrier_gateway %}
{{ route.carrier_gateway.id }}
CreateRoute
- blackhole
+ active
{% endif %}
{% if route.nat_gateway %}
{{ route.nat_gateway.id }}
+ CreateRoute
active
{% endif %}
{% if route.egress_only_igw %}
{{ route.egress_only_igw.id }}
+ CreateRoute
active
{% endif %}
{% if route.transit_gateway %}
{{ route.transit_gateway.id }}
+ CreateRoute
active
{% endif %}
{% if route.interface %}
{{ route.interface.id }}
+ CreateRoute
active
{% endif %}
diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py
index 8ceeb1e16..37de6073a 100644
--- a/moto/ec2/utils.py
+++ b/moto/ec2/utils.py
@@ -257,9 +257,13 @@ def random_ipv6_cidr():
return "2400:6500:{}:{}::/56".format(random_resource_id(4), random_resource_id(4))
-def generate_route_id(route_table_id, cidr_block, ipv6_cidr_block=None):
+def generate_route_id(
+ route_table_id, cidr_block, ipv6_cidr_block=None, prefix_list=None
+):
if ipv6_cidr_block and not cidr_block:
cidr_block = ipv6_cidr_block
+ if prefix_list and not cidr_block:
+ cidr_block = prefix_list
return "%s~%s" % (route_table_id, cidr_block)
diff --git a/tests/terraform-tests.success.txt b/tests/terraform-tests.success.txt
index 83394e12e..531a23e2b 100644
--- a/tests/terraform-tests.success.txt
+++ b/tests/terraform-tests.success.txt
@@ -115,6 +115,8 @@ TestAccAWSRouteTable_MultipleRoutes
TestAccAWSRouteTable_PrefixList_To_InternetGateway
TestAccAWSRouteTable_VpcMultipleCidrs
TestAccAWSRouteTable_IPv4_To_CarrierGateway
+TestAccAWSRouteTable_IPv4_To_InternetGateway
+TestAccAWSRouteTable_GatewayVpcEndpoint
TestAccAWSSsmDocumentDataSource
TestAccAwsEc2ManagedPrefixList
TestAccAWSEgressOnlyInternetGateway
diff --git a/tests/test_ec2/test_route_tables.py b/tests/test_ec2/test_route_tables.py
index 8b92b4b4d..f7c07a5a1 100644
--- a/tests/test_ec2/test_route_tables.py
+++ b/tests/test_ec2/test_route_tables.py
@@ -502,7 +502,7 @@ def test_routes_vpc_peering_connection():
new_route.gateway_id.should.be.none
new_route.instance_id.should.be.none
new_route.vpc_peering_connection_id.should.equal(vpc_pcx.id)
- new_route.state.should.equal("blackhole")
+ new_route.state.should.equal("active")
new_route.destination_cidr_block.should.equal(ROUTE_CIDR)
@@ -748,13 +748,19 @@ def test_create_route_with_egress_only_igw():
route_table = ec2.create_route_table(VpcId=vpc.id)
ec2_client.create_route(
- RouteTableId=route_table.id, EgressOnlyInternetGatewayId=eigw_id
+ RouteTableId=route_table.id,
+ EgressOnlyInternetGatewayId=eigw_id,
+ DestinationIpv6CidrBlock="::/0",
)
route_table.reload()
- eigw_route = [r for r in route_table.routes if r.destination_cidr_block == ""][0]
- eigw_route.egress_only_internet_gateway_id.should.equal(eigw_id)
- eigw_route.state.should.equal("active")
+ eigw_route = [
+ r
+ for r in route_table.routes_attribute
+ if r.get("DestinationIpv6CidrBlock") == "::/0"
+ ][0]
+ eigw_route.get("EgressOnlyInternetGatewayId").should.equal(eigw_id)
+ eigw_route.get("State").should.equal("active")
@mock_ec2
diff --git a/tests/test_ec2/test_vpcs.py b/tests/test_ec2/test_vpcs.py
index 002e9aac6..13151f64d 100644
--- a/tests/test_ec2/test_vpcs.py
+++ b/tests/test_ec2/test_vpcs.py
@@ -955,13 +955,13 @@ def test_delete_vpc_end_points():
route_table = ec2.create_route_table(VpcId=vpc["Vpc"]["VpcId"])
vpc_end_point1 = ec2.create_vpc_endpoint(
VpcId=vpc["Vpc"]["VpcId"],
- ServiceName="com.amazonaws.us-east-1.s3",
+ ServiceName="com.amazonaws.us-west-1.s3",
RouteTableIds=[route_table["RouteTable"]["RouteTableId"]],
VpcEndpointType="gateway",
)["VpcEndpoint"]
vpc_end_point2 = ec2.create_vpc_endpoint(
VpcId=vpc["Vpc"]["VpcId"],
- ServiceName="com.amazonaws.us-east-2.s3",
+ ServiceName="com.amazonaws.us-west-1.s3",
RouteTableIds=[route_table["RouteTable"]["RouteTableId"]],
VpcEndpointType="gateway",
)