Cloud Enterprise Network (CEN) supports flexible connectivity, isolation, and traffic redirection policies within a region. This tutorial describes how to allow isolated VPCs to access a shared services VPC while keeping them isolated from each other.
Background
An enterprise has three VPCs deployed in the China (Hangzhou) region. VPC3 hosts shared services. The goal is to allow VPC1 and VPC2 to access VPC3 while keeping VPC1 and VPC2 isolated from each other.
Network planning
Use CEN custom route tables, route table associations, and route learning to configure your network segments and routing as follows:
In this example, all three VPCs and the transit router belong to the same Alibaba Cloud account. For a cross-account deployment, see the "Cross-account VPC route isolation" section.
When you connect VPC3 to the transit router, enable the Associate with Default Route Table of Transit Router and Propagate system routes to transit router route table advanced settings.
The system route table of the transit router then automatically learns VPC3 routes, and VPC3 forwards traffic through this system route table.
When you connect VPC1 and VPC2 to the transit router, enable only the Propagate system routes to transit router route table advanced setting. Then, associate VPC1 and VPC2 with a custom route table on the transit router and add a custom route entry that points to VPC3.
The transit router's system route table learns routes from VPC1 and VPC2. VPC1 and VPC2 forward traffic to VPC3 through the custom route table, which prevents VPC1 and VPC2 from communicating with each other.
Add a route to 0.0.0.0/0 in the route tables of VPC1, VPC2, and VPC3. Set the next hop for this route to the transit router.
The following table details the network plan for the VPCs.
ImportantWhen you plan your network, ensure that the CIDR blocks of the VPCs do not overlap.
VPC
vSwitch
vSwitch zone
CIDR block
ECS
VPC1
Primary CIDR block: 192.168.0.0/16
vSwitch1
Zone A
192.168.0.0/24
ECS1 address:
192.168.0.224
vSwitch2
Zone B
192.168.1.0/24
VPC2
Primary CIDR block: 172.16.0.0/16
vSwitch3
Zone A
172.16.0.0/24
ECS2 address:
172.16.0.222
vSwitch4
Zone B
172.16.1.0/24
VPC3
Primary CIDR block: 10.0.0.0/16
vSwitch5
Zone A
10.0.0.0/24
ECS3 address:
10.0.0.112
vSwitch6
Zone B
10.0.1.0/24
Procedure
You can complete this tutorial by using the Alibaba Cloud console or Terraform.
Console
Step 1: Create a CEN instance
Create a CEN instance before you connect your network instances.
Log on to the CEN console.
On the CEN Instance page, click Create CEN Instance.
In the Create CEN Instance dialog box, configure the following parameters and click OK.
Name: Enter a name for the CEN instance.
Description: Enter a description for the CEN instance.
Step 2: Create VPC connections
On the CEN Instance page, click the ID of your CEN instance.
On the Basic Settings tab, in the VPC section, click the
icon.On the Connection with Peer Network Instance page, configure the following parameters and click OK.
Instance Type: VPC is selected by default.
Region: Select the region where the network instance is deployed. In this example, China (Hangzhou) is selected.
Transit Router: The system automatically creates a transit router in the selected region.
Account: Select the type of account that owns the network instance. In this example, the default value Your Account is used.
Billing method: The default value is pay-as-you-go.
Connection Name: Enter a name for the connection.
Networks: Select the ID of the VPC that you want to connect. In this example, VPC3 is selected.
vSwitch: Select vSwitch instances in zones that are supported by the transit router.
For single-zone regions, select one vSwitch. For multi-zone regions, select at least two vSwitches in different zones. To reduce latency, select one vSwitch per zone.
Advanced Settings: In this example, for VPC3, enable only Associate with Default Route Table of Transit Router and Propagate system routes to transit router route table.
Three options are enabled by default: Associate with default route table of transit router (associates the VPC connection with the transit router's default route table), Propagate system routes to default route table of transit router (advertises VPC system routes to the transit router, enabling communication with other attached network instances), and Automatically create route that points to transit router and add to all route tables of current VPC (adds three routes — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 — to all VPC route tables, with next hops pointing to the transit router; by default, transit routers do not advertise routes to VPCs). To customize routing, clear these checkboxes and configure route associations and propagation manually. See Manage routes.
NoteFor IPv6 traffic, after creating the VPC connection, enable route synchronization or manually add IPv6 route entries pointing to the VPC connection in the VPC.
After the connection for VPC3 is created, click Create More Connections.
After the VPC connections are created, click Return to the List to go back to the instance details page.
Step 3: Associate VPCs with a custom route table
On the instance details page, find the transit router that you created and click its ID.
On the transit router details page, click the Route Table tab.
In the left-side pane of the tab, click Create Route Table.
In the Create Route Table dialog box, configure the following parameters and click OK.
Transit Router: The system automatically selects the transit router in the current region.
Name: Enter a name for the route table.
Description: Enter a description for the route table.
Multi-region ECMP Routing: Keep the default value.
Click View Route Table Details to return to the Route Table tab.
On the Route Table tab, select the custom route table that you just created, click the Route Table Association tab, and then click Create Association.
In the Add Association dialog box, select the network instance connections to associate with this custom route table, and then click OK.
After the association, VPC1 and VPC2 forward traffic by looking up this route table.
On the details page of the custom route table, click the Route Entry tab, and then click Add Route Entry.
In the Add Route Entry dialog box, configure the following parameters and click OK.
Route Table: The system automatically selects the current custom route table.
Transit Router ID: The system automatically selects the transit router in the current region.
Name: Enter a name for the route entry.
Destination CIDR: Enter the destination CIDR block for the route. In this example, enter 10.0.0.0/16.
Blackhole Route: If you select this option, all traffic destined for this route is dropped. In this example, select No.
Next Hop: Select the next hop for the route. In this example, select the VPC3 connection.
Description: Enter a description for the route entry.
Step 4: Add a default route to each VPC
In the VPC console, add a route with the destination 0.0.0.0/0 to the route tables of VPC1, VPC2, and VPC3. Set the next hop for the route to the transit router.
Log on to the VPC console.
In the left-side navigation pane, click Route Table.
In the top navigation bar, select the region where the route table resides.
On the Route Table page, find the target route table and click its ID.
In this example, select the route table for VPC3.
On the route table details page, on the Route Entry List tab, click Custom Route, and then click Add Route Entry.
In the Add Route Entry panel, configure the following parameters and click OK.
Name: Enter a name for the route entry.
Destination CIDR Block: Enter the destination CIDR block. In this example, enter 0.0.0.0/0.
Next Hop Type: Select the type of the next hop. In this example, select Transit Router.
Transit Router: Select the network instance connection. In this example, select the VPC3 connection.
For more information about the parameters, see Manage network traffic by using a custom route table.
Repeat step 4 to step 6 to add a route with the destination 0.0.0.0/0 and the next hop pointing to the transit router for VPC1 and VPC2.
You can view the routing information for VPC1, VPC2, VPC3, and the transit router route tables on the transit router details page in the CEN console.
On the transit router details page, click Network Instance Route Table to view the routes for VPC1, VPC2, and VPC3.
On the transit router details page, click Network Instance Route Table.
From the Networks drop-down list, select the ID of VPC1, VPC2, or VPC3 to view its routes.
Figure 1. Routes of VPC1

Figure 2. Routes of VPC2

Figure 3. Routes of VPC3

On the Route Table tab, you can view the routes that the system route table of the transit router has learned from VPC1, VPC2, and VPC3.
On the transit router details page, click Route Table.
On the Route Table tab, view the route entries in the route table.
Figure 4. System route table

Figure 5. Custom route table

Step 5: Test network connectivity
Test the connectivity among VPC1, VPC2, and VPC3.
Before you begin, verify that the security group rules for the ECS instances in VPC1, VPC2, and VPC3 allow communication between the instances. For more information, see View security group rules.
Log on to the ECS instance in VPC1. For more information, see Connection methods for ECS instances.
Run the ping command to ping the IP address of the ECS instance in VPC3 and test the connectivity between VPC1 and VPC3.
The output confirms that VPC1 and VPC3 can communicate.

Log on to the ECS instance in VPC2 and use the ping command to ping the IP address of the ECS instance in VPC3 to test the connectivity between VPC2 and VPC3.
The output confirms that VPC2 and VPC3 can communicate.

Log in to the ECS instance in VPC1 and use the ping command to ping the IP address of the ECS instance in VPC2 to test the connectivity between VPC1 and VPC2.
The output confirms that VPC1 and VPC2 cannot communicate.

Cross-account VPC route isolation
The routing and isolation mechanism described in this tutorial applies identically to cross-account deployments. Isolation is still achieved by enabling only route learning (Propagate system routes to transit router route table) for VPC1 and VPC2, associating them with a custom route table, and adding a custom route to VPC3 in that route table. This mechanism does not depend on which Alibaba Cloud account the VPCs belong to.
Prerequisite: Before you create a cross-account VPC connection, the account that owns the VPC must grant authorization to the account that owns the transit router. For instructions, see Cross-account authorization for network instances.
Configuration difference: In Step 2: Create VPC connections, for the Account field, select Different Account instead of Your Account, and enter the primary account ID of the Alibaba Cloud account that owns the VPC. All other configuration items are the same as in the same-account scenario. For parameter details, see Create a VPC connection.
Operation ownership: Step 1 through Step 3 (creating the CEN instance, the transit router, the VPC connections, and the custom route table with its route entries) are all performed in the account that owns the transit router. Step 4: Add a default route to each VPC must be performed by each VPC's own account, in that account's own VPC console.
Cross-account VPC isolation by using route maps
After a cross-account VPC is connected to CEN, it is fully connected to all other VPC instances on the transit router by default. To selectively isolate a cross-account VPC from specific VPC instances, configure a route map on the transit router's route table instead of using the custom route table and route table association method described earlier in this topic. This mechanism is independent of the custom-route-table-based isolation described in Cross-account VPC route isolation: it achieves isolation by filtering route advertisements at the control plane, not by changing which route table a VPC attachment uses.
How it works: A route map controls which routes the transit router advertises to a given VPC attachment. When you create a Deny route map that matches traffic between two VPC attachments, the transit router stops advertising the corresponding routes, so the two VPC instances can no longer reach each other, even though the underlying route tables are not modified.
Before you begin: A route map takes effect only for route advertisements that occur after the route map is created. If a route entry that enables communication between the two VPC instances already exists in the route table, delete that route entry first. Otherwise, the existing route continues to work and the isolation does not take effect.
To configure a deny route map:
Create a route map on the transit router's route table with the following settings:
Action: Deny.
Priority: 20. A lower value indicates a higher priority.
Direction: Egress from the regional gateway (the route map filters routes as they are advertised out of the region).
Source instance IDs: the ID of the cross-account VPC attachment, for example,
vpc-xxx.Destination instance IDs: the ID of the VPC attachment that you want to isolate from the source VPC, for example,
vpc-yyy.
NoteIn some cases, the Source instance IDs drop-down list on the route map creation page in the console shows no selectable options, even if the VPC connection has already been associated with the route table through route table association. If this occurs, call the CreateCenRouteMap operation instead, and pass the VPC instance ID in the
vpc-xxxformat to create the route map.After the route map takes effect, log on to the ECS instance in the source VPC and run the ping command to test connectivity to an ECS instance in the isolated VPC. The ping command should fail (100% packet loss), which confirms that the route map isolation is in effect.
Terraform
You can use Terraform to build the environment for this tutorial. For instructions on installing and configuring Terraform, see Install Terraform.
The following procedure describes how to run Terraform v1.9.8 on a Linux host. Before you start, make sure that you have configured Authentication.
Some resources in this tutorial incur fees. To avoid unexpected charges, release the resources when they are no longer needed.
Step 1: Create resources
The following code defines all the resources for this scenario. Save it as a .tf file in a new directory.
variable "pname" {
description = "The prefix name for the resources"
type = string
default = "tf-CenSharedVpc"
}
variable "default_region" {
description = "Default region"
type = string
default = "cn-hangzhou"
}
variable "az_list" {
description = "List of availability zones to use"
type = list(string)
default = ["cn-hangzhou-j", "cn-hangzhou-k"]
}
variable "vpc_cidr_list" {
description = "List of VPC CIDR block"
type = list(string)
default = ["192.168.0.0/16", "172.16.0.0/16", "10.0.0.0/16"]
}
variable "vsw_cidr_list" {
description = "List of VSW CIDR block"
type = list(string)
default = [
"192.168.0.0/24", "192.168.1.0/24",
"172.16.0.0/24", "172.16.1.0/24",
"10.0.0.0/24", "10.0.1.0/24"
]
}
variable "ecs_ip_list" {
description = "List of ECS ip"
type = list(string)
default = ["192.168.0.124", "172.16.0.222", "10.0.0.112"]
}
provider "alicloud" {
region = var.default_region
}
# --- 3vpc 6vsw 3ecs
resource "alicloud_vpc" "vpc" {
count = length(var.vpc_cidr_list)
vpc_name = "${var.pname}-vpc${count.index + 1}"
cidr_block = var.vpc_cidr_list[count.index]
}
resource "alicloud_vswitch" "vsw" {
count = length(var.vsw_cidr_list)
vpc_id = alicloud_vpc.vpc[floor(count.index / length(var.az_list))].id
cidr_block = var.vsw_cidr_list[count.index]
zone_id = var.az_list[count.index % length(var.az_list)]
vswitch_name = "${var.pname}-vsw${count.index + 1}"
}
resource "alicloud_instance" "ecs" {
count = length(var.vpc_cidr_list)
instance_name = "${var.pname}-ecs${count.index + 1}"
instance_type = "ecs.e-c1m1.large"
security_groups = [alicloud_security_group.sg[count.index].id]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list)].id
image_id = "aliyun_3_x64_20G_qboot_alibase_20230727.vhd"
system_disk_category = "cloud_essd"
private_ip = var.ecs_ip_list[count.index]
instance_charge_type = "PostPaid"
}
# --- 3 sg
resource "alicloud_security_group" "sg" {
count = length(var.vpc_cidr_list)
name = "${var.pname}-${count.index + 1}"
vpc_id = alicloud_vpc.vpc[count.index].id
}
resource "alicloud_security_group_rule" "allow_inbound_ssh" {
count = length(var.vpc_cidr_list)
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = alicloud_security_group.sg[count.index].id
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_security_group_rule" "allow_inbound_icmp" {
count = length(var.vpc_cidr_list)
type = "ingress"
ip_protocol = "icmp"
nic_type = "intranet"
policy = "accept"
port_range = "-1/-1"
priority = 1
security_group_id = alicloud_security_group.sg[count.index].id
cidr_ip = "0.0.0.0/0"
}
# --- cen and tr
resource "alicloud_cen_instance" "cen" {
cen_instance_name = "${var.pname}-cen1"
}
resource "alicloud_cen_transit_router" "tr" {
transit_router_name = "${var.pname}-tr"
cen_id = alicloud_cen_instance.cen.id
}
data "alicloud_cen_transit_router_route_tables" "tr" { # get tr sys table
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
transit_router_route_table_type = "System"
}
# 3 attach
resource "alicloud_cen_transit_router_vpc_attachment" "attach" {
count = length(var.vpc_cidr_list)
cen_id = alicloud_cen_instance.cen.id
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
vpc_id = alicloud_vpc.vpc[count.index].id
zone_mappings {
zone_id = var.az_list[0]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list)].id
}
zone_mappings {
zone_id = var.az_list[1]
vswitch_id = alicloud_vswitch.vsw[count.index * length(var.az_list) + 1].id
}
transit_router_vpc_attachment_name = "attach${count.index + 1}"
}
# 3 propa
resource "alicloud_cen_transit_router_route_table_propagation" "propa" {
count = length(var.vpc_cidr_list)
transit_router_route_table_id = data.alicloud_cen_transit_router_route_tables.tr.tables[0].id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[count.index].transit_router_attachment_id
}
# 1 custom_table
resource "alicloud_cen_transit_router_route_table" "custom_table" { # create tr custom_table
transit_router_id = alicloud_cen_transit_router.tr.transit_router_id
transit_router_route_table_name = "custom_table"
}
resource "alicloud_cen_transit_router_route_entry" "tr_entry" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_route_entry_destination_cidr_block = "10.0.0.0/16"
transit_router_route_entry_next_hop_type = "Attachment"
transit_router_route_entry_name = "entry1_name"
transit_router_route_entry_description = "entry1_desc"
transit_router_route_entry_next_hop_id = alicloud_cen_transit_router_vpc_attachment.attach[2].transit_router_attachment_id
}
# associate attach1\2 custom_table
resource "alicloud_cen_transit_router_route_table_association" "ass1" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[0].transit_router_attachment_id
}
resource "alicloud_cen_transit_router_route_table_association" "ass2" {
transit_router_route_table_id = alicloud_cen_transit_router_route_table.custom_table.transit_router_route_table_id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[1].transit_router_attachment_id
}
# ass attach3 sys_table
resource "alicloud_cen_transit_router_route_table_association" "ass3" {
transit_router_route_table_id = data.alicloud_cen_transit_router_route_tables.tr.tables[0].id
transit_router_attachment_id = alicloud_cen_transit_router_vpc_attachment.attach[2].transit_router_attachment_id
}
# vpc entry
resource "alicloud_route_entry" "vpc_entry" {
count = length(var.vpc_cidr_list)
route_table_id = alicloud_vpc.vpc[count.index].route_table_id
destination_cidrblock = "0.0.0.0/0"
nexthop_type = "Attachment"
nexthop_id = alicloud_cen_transit_router_vpc_attachment.attach[count.index].transit_router_attachment_id
}
output "ecs1_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[0].id}"
}
output "ecs2_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[1].id}"
}
output "ecs3_login_address" {
value = "https://ecs-workbench.alibabacloud.com/?from=EcsConsole&instanceType=ecs®ionId=${var.default_region}&instanceId=${alicloud_instance.ecs[2].id}"
}Step 2: Test network connectivity
Follow these steps to test the connectivity among VPC1, VPC2, and VPC3.
Log on to the ECS1 instance in VPC1 (instance name:
tf-CenSharedVpc-ecs1).Find the login URL for ECS1 in the Terraform outputs. Open the URL in your browser and use Temporary SSH Key-based authentication.

Run the ping command and ping the IP address of the ECS3 instance in VPC3 to test the connectivity between VPC1 and VPC3.
ping 10.0.0.112The output confirms that VPC1 and VPC3 can communicate.

Log on to the ECS2 instance (
tf-CenSharedVpc-ecs2) in VPC2 and run the ping command to ping the IP address of the ECS3 instance in VPC3 to test the connectivity between VPC2 and VPC3.ping 10.0.0.112The output confirms that VPC2 and VPC3 can communicate.

Log on to the ECS1 instance (
tf-CenSharedVpc-ecs1) in VPC1. Use the ping command to ping the IP address of the ECS2 instance in VPC2 to test the connectivity between VPC1 and VPC2.ping 172.16.0.222The output confirms that VPC1 and VPC2 cannot communicate.

Step 3: Clean up resources
After verification, run the following command to release the resources.
terraform destroy --auto-approve