Use Terraform to create a VPC firewall to protect traffic between two VPCs connected by using an Express Connect circuit
Provision a VPC firewall that inspects traffic between two VPCs connected by an Express Connect circuit. The Terraform configuration in this topic creates all required resources in a single terraform apply run: two VPCs with vSwitches, a peering connection, route entries, and the firewall itself.
Run the sample code in this topic directly in your browser. Visit Terraform Explorer.
Resources used
alicloud_cloud_firewall_vpc_firewall: VPCboundary firewall。
Create a VPC firewall
Step 1: Write the configuration
Create a working directory and a main.tf file inside it. The following configuration provisions all required resources in sequence: two VPCs with vSwitches, a peering connection, route entries, and the VPC firewall.
Provider and VPCs
The configuration targets the cn-heyuan region. It creates two VPCs with non-overlapping CIDR blocks and two vSwitches in each VPC across two availability zones.
variable "region" {
default = "cn-heyuan"
}
provider "alicloud" {
region = var.region
}
# Retrieve the current Alibaba Cloud account ID.
data "alicloud_account" "current" {
}
# VPC 1 (initiator)
resource "alicloud_vpc" "vpc" {
vpc_name = "dd-tf-vpc-01"
cidr_block = "192.168.0.0/16"
}
# VPC 2 (acceptor)
resource "alicloud_vpc" "vpc1" {
vpc_name = "dd-tf-vpc-02"
cidr_block = "172.16.0.0/12"
}
# vSwitches for VPC 1
resource "alicloud_vswitch" "vsw" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "192.168.10.0/24"
zone_id = "cn-heyuan-a"
vswitch_name = "dd-tf-vpc-01-example-1"
}
resource "alicloud_vswitch" "vsw1" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "192.168.20.0/24"
zone_id = "cn-heyuan-b"
vswitch_name = "dd-tf-vpc-01-example-2"
}
# vSwitches for VPC 2
resource "alicloud_vswitch" "vsw2" {
vpc_id = alicloud_vpc.vpc1.id
cidr_block = "172.16.10.0/24"
zone_id = "cn-heyuan-a"
vswitch_name = "dd-tf-vpc-02-example-11"
}
resource "alicloud_vswitch" "vsw3" {
vpc_id = alicloud_vpc.vpc1.id
cidr_block = "172.16.20.0/24"
zone_id = "cn-heyuan-b"
vswitch_name = "dd-tf-vpc-02-example-22"
}VPC peering connection
The peering connection links VPC 1 (initiator) to VPC 2 (acceptor). Both VPCs are in the same region, so accepting_region_id matches the provider region.
resource "alicloud_vpc_peer_connection" "default" {
peer_connection_name = "terraform-example-vpc-peer-connection"
vpc_id = alicloud_vpc.vpc.id
accepting_ali_uid = data.alicloud_account.current.id
accepting_region_id = "cn-heyuan"
accepting_vpc_id = alicloud_vpc.vpc1.id
description = "terraform-example"
force_delete = true
}
resource "alicloud_vpc_peer_connection_accepter" "default" {
instance_id = alicloud_vpc_peer_connection.default.id
force_delete = true
}Route entries
Each VPC needs a route entry that directs traffic destined for the peer's CIDR block through the peering connection.
# Route from VPC 1 toward VPC 2
resource "alicloud_route_entry" "foo" {
route_table_id = alicloud_vpc.vpc.route_table_id
destination_cidrblock = "1.2.3.4/32"
nexthop_type = "VpcPeer"
nexthop_id = alicloud_vpc_peer_connection.default.id
}
# Route from VPC 2 toward VPC 1
resource "alicloud_route_entry" "foo1" {
route_table_id = alicloud_vpc.vpc1.route_table_id
destination_cidrblock = "4.3.X.X/32"
nexthop_type = "VpcPeer"
nexthop_id = alicloud_vpc_peer_connection.default.id
}Wait resources
The VPC firewall API requires the peering connection and route entries to be fully propagated before the firewall can be created. The time_sleep resource introduces a 12-minute wait (720 seconds) for propagation. Adjust create_duration based on your network conditions.
resource "time_sleep" "wait_before_firewall" {
depends_on = [
alicloud_route_entry.foo,
alicloud_route_entry.foo1
]
create_duration = "720s"
}
resource "null_resource" "wait_for_firewall" {
provisioner "local-exec" {
command = "echo waiting for firewall to be ready"
}
depends_on = [time_sleep.wait_before_firewall]
}VPC firewall
The alicloud_cloud_firewall_vpc_firewall resource creates the firewall. It references both VPCs, their route tables, and the peering connection as the next hop. Setting status = "open" enables the firewall immediately after creation.
resource "alicloud_cloud_firewall_vpc_firewall" "default" {
depends_on = [null_resource.wait_for_firewall]
timeouts {
create = "30m"
}
vpc_firewall_name = "tf-test"
member_uid = data.alicloud_account.current.id
local_vpc {
vpc_id = alicloud_vpc.vpc.id
region_no = "cn-heyuan"
local_vpc_cidr_table_list {
local_route_table_id = alicloud_vpc.vpc.route_table_id
local_route_entry_list {
local_next_hop_instance_id = alicloud_vpc_peer_connection.default.id
local_destination_cidr = alicloud_route_entry.foo.destination_cidrblock
}
}
}
peer_vpc {
vpc_id = alicloud_vpc.vpc1.id
region_no = "cn-heyuan"
peer_vpc_cidr_table_list {
peer_route_table_id = alicloud_vpc.vpc1.route_table_id
peer_route_entry_list {
peer_destination_cidr = alicloud_route_entry.foo1.destination_cidrblock
peer_next_hop_instance_id = alicloud_vpc_peer_connection.default.id
}
}
}
# open: enable the firewall immediately after creation
# close: create the firewall in a disabled state
status = "open"
}Outputs
output "vpc_id" {
value = alicloud_vpc.vpc.id
}
output "vpc1_id" {
value = alicloud_vpc.vpc1.id
}
output "route_table_id_vpc" {
value = alicloud_vpc.vpc.route_table_id
}
output "route_table_id_vpc1" {
value = alicloud_vpc.vpc1.route_table_id
}
output "foo_nexthop_id" {
value = alicloud_vpc_peer_connection.default.id
}
output "foo1_nexthop_id" {
value = alicloud_vpc_peer_connection.default.id
}
output "cidrblock" {
value = alicloud_route_entry.foo.destination_cidrblock
}
output "cidrblock1" {
value = alicloud_route_entry.foo1.destination_cidrblock
}Step 2: Initialize Terraform
terraform initTerraform downloads the aliyun/alicloud provider and initializes the working directory. A successful run ends with:
Terraform has been successfully initialized!For Terraform 0.13 and later, the provider source has moved toaliyun/alicloud. Updaterequired_providersin your configuration if you see a registry warning.
Step 3: Preview the execution plan
terraform planReview the list of resources Terraform will create before applying changes.
Step 4: Apply the configuration
terraform applyWhen prompted, enter yes and press Enter. The process takes approximately 25 minutes because of the 12-minute propagation wait and the firewall creation. A successful run ends with:
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.Verify the result
Using the CLI
List all resources in the Terraform state and inspect the firewall details:
terraform state list
terraform showThe terraform show output includes the firewall ID (prefixed with vfw-) and its current status. Verify that status is open and that vpc_firewall_name is tf-test.
Using the console
Log on to the Cloud Firewall console.
Go to Cloud Firewall consoleFirewall Settings and click the VPC Firewall tab.
Search for the firewall by its ID to view its configuration and status.

Clean up resources
To delete all resources created by this configuration:
terraform destroyFor more information, see Common commands.
Complete sample code
Run the sample code directly in your browser at Terraform Explorer.
variable "region" {
default = "cn-heyuan"
}
provider "alicloud" {
region = var.region
}
data "alicloud_account" "current" {
}
resource "alicloud_vpc" "vpc" {
vpc_name = "dd-tf-vpc-01"
cidr_block = "192.168.0.0/16"
}
resource "alicloud_vpc" "vpc1" {
vpc_name = "dd-tf-vpc-02"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "vsw" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "192.168.10.0/24"
zone_id = "cn-heyuan-a"
vswitch_name = "dd-tf-vpc-01-example-1"
}
resource "alicloud_vswitch" "vsw1" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "192.168.20.0/24"
zone_id = "cn-heyuan-b"
vswitch_name = "dd-tf-vpc-01-example-2"
}
resource "alicloud_vswitch" "vsw2" {
vpc_id = alicloud_vpc.vpc1.id
cidr_block = "172.16.10.0/24"
zone_id = "cn-heyuan-a"
vswitch_name = "dd-tf-vpc-02-example-11"
}
resource "alicloud_vswitch" "vsw3" {
vpc_id = alicloud_vpc.vpc1.id
cidr_block = "172.16.20.0/24"
zone_id = "cn-heyuan-b"
vswitch_name = "dd-tf-vpc-02-example-22"
}
resource "alicloud_vpc_peer_connection" "default" {
peer_connection_name = "terraform-example-vpc-peer-connection"
vpc_id = alicloud_vpc.vpc.id
accepting_ali_uid = data.alicloud_account.current.id
accepting_region_id = "cn-heyuan"
accepting_vpc_id = alicloud_vpc.vpc1.id
description = "terraform-example"
force_delete = true
}
resource "alicloud_vpc_peer_connection_accepter" "default" {
instance_id = alicloud_vpc_peer_connection.default.id
force_delete = true
}
resource "alicloud_route_entry" "foo" {
route_table_id = alicloud_vpc.vpc.route_table_id
destination_cidrblock = "1.2.3.4/32"
nexthop_type = "VpcPeer"
nexthop_id = alicloud_vpc_peer_connection.default.id
}
resource "alicloud_route_entry" "foo1" {
route_table_id = alicloud_vpc.vpc1.route_table_id
destination_cidrblock = "4.3.X.X/32"
nexthop_type = "VpcPeer"
nexthop_id = alicloud_vpc_peer_connection.default.id
}
resource "time_sleep" "wait_before_firewall" {
depends_on = [
alicloud_route_entry.foo,
alicloud_route_entry.foo1
]
create_duration = "720s"
}
resource "null_resource" "wait_for_firewall" {
provisioner "local-exec" {
command = "echo waiting for firewall to be ready"
}
depends_on = [time_sleep.wait_before_firewall]
}
resource "alicloud_cloud_firewall_vpc_firewall" "default" {
depends_on = [null_resource.wait_for_firewall]
timeouts {
create = "30m"
}
vpc_firewall_name = "tf-test"
member_uid = data.alicloud_account.current.id
local_vpc {
vpc_id = alicloud_vpc.vpc.id
region_no = "cn-heyuan"
local_vpc_cidr_table_list {
local_route_table_id = alicloud_vpc.vpc.route_table_id
local_route_entry_list {
local_next_hop_instance_id = alicloud_vpc_peer_connection.default.id
local_destination_cidr = alicloud_route_entry.foo.destination_cidrblock
}
}
}
peer_vpc {
vpc_id = alicloud_vpc.vpc1.id
region_no = "cn-heyuan"
peer_vpc_cidr_table_list {
peer_route_table_id = alicloud_vpc.vpc1.route_table_id
peer_route_entry_list {
peer_destination_cidr = alicloud_route_entry.foo1.destination_cidrblock
peer_next_hop_instance_id = alicloud_vpc_peer_connection.default.id
}
}
}
status = "open"
}
output "vpc_id" {
value = alicloud_vpc.vpc.id
}
output "vpc1_id" {
value = alicloud_vpc.vpc1.id
}
output "route_table_id_vpc" {
value = alicloud_vpc.vpc.route_table_id
}
output "route_table_id_vpc1" {
value = alicloud_vpc.vpc1.route_table_id
}
output "foo_nexthop_id" {
value = alicloud_vpc_peer_connection.default.id
}
output "foo1_nexthop_id" {
value = alicloud_vpc_peer_connection.default.id
}
output "cidrblock" {
value = alicloud_route_entry.foo.destination_cidrblock
}
output "cidrblock1" {
value = alicloud_route_entry.foo1.destination_cidrblock
}