ANS Exercise 1.2: VPC Peering

ANS Exercise 1.2: VPC Peering

In this exercise we will set up VPC peering within the same region. We will experiment with routes, referencing security groups in different VPCs, overlapping CIDRs, and transitive routing.

In this exercise we will not complicate matters with private subnets and NAT. Instead, we will use public subnets only.

This is exercise 1.2 for the AWS Advanced Networking Specialty training. For an explanation and overview of all exercises, see the overview post.

The exercises are built on the assumption that you’re already familiar with the AWS basics and have achieved at least one associate level AWS certification.

Creating three VPCs in one region

We will get started by creating three VPCs, called ans-exercise-1.2-vpc-a, ans-exercise-1.2-vpc-b, and ans-exercise-1.2-vpc-c. We will use the CIDR ranges 10.0.0.0/16, 192.168.0.0/16 and 172.16.0.0/16, respectively.

The easiest way to launch VPCs is to use the Launch VPC Wizard. To start the wizard, open the VPC console, navigate to the VPC Dashboard and click the “Launch VPC Wizard” button.

1.2-launch-vpc-wizard

1.2-select-vpc-configuration

Select the “VPC with a Single Public Subnet” option and fill in the details as follows.

1.2-vpc-wizard-options

Click “Create VPC” and repeat for the other two VPCs. The end result should look like this:

1.2-vpcs-overview

1.2-subnets-overview

Adding EC2 instances

Launch an EC2 instance in every VPC. They can be small instances (eg. t2.micro). Make sure that you:

  • assign a public IP address to every instance
  • assign a descriptive Name tag to the instances
  • open port 22 to your IP address
  • configure the key pair so you can SSH to the instance

You will find that you have to create three separate security groups, because each security group is bound to a specific VPC.

When you’re done, you should have an overview like this:

1.2-running-instances

Start SSH sessions and test connectivity between the instances

Log in to every instance and try to ping the other instances. Of course this won’t work, because the VPCs are in no way linked, and the instances live in completely separate subnets.

[[email protected] ~]$ ping -c 1 192.168.0.223
PING 192.168.0.223 (192.168.0.223) 56(84) bytes of data.

--- 192.168.0.223 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

[[email protected] ~]$ ping -c 1 172.16.0.8
PING 172.16.0.8 (172.16.0.8) 56(84) bytes of data.

--- 172.16.0.8 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

Set up VPC Peering

We will set up VPC Peering so that VPC B is connected to A and C, but C and A are not connected.

1.2-vpc-peering-overview

Open the VPC Console and click Peering Connections. Then click the “Create Peering Connection” button.

Fill in the fields to connect VPC A to VPC B.

1.2-peering-connection-a-b

After you’ve filled in the details and clicked the “Create Peering Connection” button, you will find a peering connection pending acceptance. Click the Actions button and accept the request.

1.2-accept-request

Repeat the same steps to set up a connection between VPC B and C.

Setting up routing

When you accept the peering connections, you will see a popup like this:

1.2-accept-peering-set-up-routing

The message says “To send and receive traffic across this VPC peering connection, you must add a route to the peered VPC in one or more of your VPC route tables.”, so let’s do that now.

We will need to set up the following routes:

  • VPC A needs to know how to reach VPC B
  • VPC B needs to know how to reach VPC A
  • VPC B needs to know how to reach VPC C
  • VPC C needs to know how to reach VPC B

The Route Table tab contains an overview of all route tables in all VPCs. This is a bit hard to parse, so we’ll navigate to the Subnets tab instead. Select the VPC A subnet and click the Route Table tab in the bottom.

1.2-edit-route-table

From here, click the route table link (rtb-01adcee467c0bd700 in my screenshot). This will filter the correct route table in the Route Table tab. Click the Routes tab in the bottom, then click the “Edit Routes” button.

1.2-edit-routes-button

Click the “Add route” button and fill in the CIDR for VPC B (192.168.0.0/16). Then select the peering connection between A and B. This will tell the AWS implicit router that any traffic for the 192.168.0.0/16 CIDR should be routed over this peering connection.

1.2-select-peering-connection

Go back to the Subnets tab and select the VPC B subnet. Like before, click the Route Table tab in the bottom and click the link to the correct route table.

1.2-edit-routes-vpc-b-button

Because VPC B is connected to both VPC A and C, we will need to add two routes to this route table. Make sure that you forward traffic for a CIDR to the correct peering connection.

Select Peering Connection VPC B

When you’ve set up the peering connections for VPC B, finish up by adding the last route to VPC C’s route table.

Note: you could theoretically select a smaller range for a peering connection. For example, we could route 192.168.0.0/24 from VPC A to B, instead of 192.168.0.0/16. However, VPC Peering is limited to exactly one peering connection between two VPCs. So in this example, we would not be able to also route 192.168.1.0/24 from VPC A to VPC B.

Accepting traffic in the security groups

After setting up the routes in the previous step, the routers ‘know’ how to send traffic between the VPCs. However, we have not allowed any traffic between the instances yet. Let’s do that now.

Navigate to the instance in VPC B in the EC2 console and select its security group.

1.2-select-security-group

Then click the Inbound tab and press the Edit button.

1.2-edit-security-group

Click the Add Rule button twice and fill in the following rules, allowing ping traffic from VPCs A and C.

1.2-allow-all-icmp-vpc-a-c

Now SSH back into the instance in VPC A, and try to ping the instance in VPC B again.

[[email protected] ~]$ ping -c 1 192.168.0.223
PING 192.168.0.223 (192.168.0.223) 56(84) bytes of data.
64 bytes from 192.168.0.223: icmp_seq=1 ttl=255 time=0.452 ms

--- 192.168.0.223 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.452/0.452/0.452/0.000 ms

As you can see, this works perfectly!

Allowing access by security group

In the previous step we’ve allowed the instance in VPC A to ping the instance in VPC B. We’ve done this by whitelisting VPC A’s entire CIDR on the instance in VPC B.

Now let’s allow the instance in VPC B to ping the instance in VPC A as well, but do it by whitelisting the instance’s security group.

First, look up and copy the security group ID for the instance in VPC B:

1.2-select-instance-b-security-group

Then select VPC A’s instance security group:

1.2-select-security-group-vpc-a

Navigate to the Inbound tab and click Edit again:

1.2-edit-security-group-vpc-a

Fill in the the security group ID for the instance in VPC B that you just copied:

1.2-add-security-group-rule

Click Save and open an SSH connection to the instance in VPC B. From there, try to ping the instance in VPC A. If all was configured well, this should succeed!


       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
5 package(s) needed for security, out of 13 available
Run "sudo yum update" to apply all updates.
[[email protected] ~]$ ping -c 1 10.0.0.82
PING 10.0.0.82 (10.0.0.82) 56(84) bytes of data.
64 bytes from 10.0.0.82: icmp_seq=1 ttl=255 time=0.394 ms

--- 10.0.0.82 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.394/0.394/0.394/0.000 ms

A quick overview of what we’ve built so far:

1.2-vpc-peering-overview-annotated

Note: Referencing security groups by ID like we’ve done above only works within the same region. See the last chapter in this post for an example.

Transitive traffic

Since our VPCs are connected like this: A <-> B <-> C, you might expect that it would be possible to connect from an instance in VPC A to an instance in VPC C too. However, this is not the case. The implicit router for each VPC will only allow traffic when either the source or the destination IP address resides in the VPC.

A few examples:

  • VPC B will accept an inbound connection from 10.0.0.82 to 192.168.0.223, because the 192.168.0.223 address resides in the 192.168.0.0/16 CIDR.
  • VPC A will accept an outbound connection from 10.0.0.82 to 192.168.0.223, because the 10.0.0.82 address resides in the 10.0.0.0/16 CIDR.
  • VPC B will reject an inbound connection from 10.0.0.82 to 172.16.0.8, because neither address resides in the 192.168.0.0/16 CIDR.

There are three solutions for this problem:

  • Create a VPC peering between VPC A and C.
  • Create a VPN overlay network.
  • Use Transit Gateway, a technology built for transitive traffic.

VPC star pattern peering

When you have only three VPCs, a link between VPC A and VPC C makes sense and is perfectly manageable. However, as the number of VPCs grow, the number of VPC peerings grow exponentially. See the diagram with five VPCs below; it requires 10 peering connections. Six VPCs would require 15 connections. Seven VPCs require 21 connections, and so on. This is a lot to maintain.

1.2-star-pattern

Because managing this architecture is difficult, network architects have opted for a simpler solution; the VPN overlay network.

VPN overlay network

In a VPN overlay network, all VPCs or EC2 instances connect to a central VPN server in a Transit VPC. All inter-VPC traffic is routed over the VPN server, which in turn routes the traffic to the correct VPC.

Because the VPNs are set up using the VPN server’s IP address, the VPC sees inbound traffic is targeted at an IP address in its own CIDR, and will allow it.

1.2-vpn-overlay

The VPN Server does not have the same source-destination-check restrictions the VPC does (although you have to disable the check on the EC2 instance), so it can route traffic between CIDRs that are not its own.

The downside of this solution is that you need to manage and scale an EC2 based VPN server. To solve this issue, Amazon has released Transit Gateway.

Transit Gateway

Transit Gateway is a technology that allows multiple VPCs, VPNs and Direct Connect to connect to a single gateway. This gateway does not have any source-destination restrictions, and can be configured to route entire CIDRs, partial CIDRs or no traffic between it associated networks. It is fully managed by Amazon and has a very high bandwidth capacity.

1.2-transit-gateway

Overlapping CIDRs

Create a new VPC (called ans-exercise-1.2-vpc-d) and assign the 10.0.0.0/16 CIDR to it. This is the same CIDR as VPC A.

1.2-create-vpc-d

Next, try to create a VPC peering between VPC A and D:

1.2-create-peering-connection-a-d

This will result in an error A peering connection cannot be created between 2 VPCs that have overlapping CIDRs. Please select 2 VPCs which have distinct CIDRs.:

1.2-peering-error

Because AWS does not allow you to override the local route, or to create a route more specific than the local route, it would be impossible to create a route to the peered VPC. As such, creating this peering connection will always be useless and is therefore blocked.

Luc van Donkersgoed
Luc van Donkersgoed