A VPC is not a private network inside the cloud; it’s a logical construct that defines your private network space within the cloud provider’s infrastructure.

Let’s watch this in action. Imagine you’re setting up a new application in AWS. You start by defining a Virtual Private Cloud (VPC).

{
  "VpcId": "vpc-0123456789abcdef0",
  "CidrBlock": "10.0.0.0/16",
  "IsDefault": false,
  "State": "available",
  "Tags": [
    {"Key": "Name", "Value": "my-app-vpc"}
  ]
}

This CidrBlock "10.0.0.0/16" allocates a private IP address range for your resources. Anything you launch within this VPC will get an IP from this range, like 10.0.1.5. The cloud provider ensures these IPs are private to your VPC, meaning they aren’t routable on the public internet and won’t conflict with other VPCs.

Now, your application needs to talk to other services, maybe in another VPC or even on-premises. This is where VPNs and Peering come in.

A Virtual Private Network (VPN) connection, specifically a Site-to-Site VPN, acts like a secure, encrypted tunnel between your VPC and another network. Think of it as building a private highway over the public internet.

Here’s a simplified representation of a VPN connection’s configuration:

Type: AWS::EC2::VPNConnection
Properties:
  VpnConnectionDescription: "Connect my-app-vpc to on-prem datacenter"
  VpnGatewayId: "vgw-0123456789abcdef0"
  CustomerGatewayId: "cgw-0123456789abcdef1"
  Type: ipsec.1
  StaticRoutesOnly: true
  StaticIpAddresses:
    - "203.0.113.1" # Public IP of your on-prem VPN device
    - "203.0.113.2" # Another public IP (for redundancy)
  Tags:
    - Key: Name
      Value: "on-prem-vpn-to-vpc"

The VpnGatewayId is on the AWS side, attached to your VPC. The CustomerGatewayId represents your on-premises VPN device (its public IP and BGP ASN, if applicable). The Type: ipsec.1 specifies the encryption protocol. Once established, traffic between the VPC’s CIDR (e.g., 10.0.0.0/16) and your on-prem CIDR (e.g., 192.168.1.0/24) flows through this encrypted tunnel, appearing as if they are on the same private network.

VPC Peering, on the other hand, is a direct, private connection between two VPCs. It’s like creating a direct cable between two separate buildings, bypassing the public internet entirely.

Consider this peering request:

{
  "VpcPeeringConnectionId": "pcx-0123456789abcdef0",
  "RequesterVpcInfo": {
    "CidrBlock": "10.0.0.0/16",
    "VpcId": "vpc-0123456789abcdef0",
    "OwnerId": "111122223333"
  },
  "AccepterVpcInfo": {
    "CidrBlock": "10.1.0.0/16",
    "VpcId": "vpc-0abcdef0123456789",
    "OwnerId": "444455556666"
  },
  "Status": {
    "Code": "pending-acceptance"
  }
}

Here, vpc-0123456789abcdef0 (your VPC) is requesting to peer with vpc-0abcdef0123456789 (another VPC, possibly in a different account). Once accepted, and crucially, once you update the route tables in both VPCs to include the other’s CIDR block, resources in 10.0.0.0/16 can directly communicate with 10.1.0.0/16 using their private IPs. For instance, a server at 10.0.1.10 could reach a database at 10.1.2.20 as if they were in the same network, without traversing the internet or any VPN gateway.

The mental model to hold is that VPCs provide the address space and isolation, VPNs provide secure connectivity over untrusted networks (like the internet), and Peering provides direct, private connectivity between VPCs.

A common pitfall is forgetting that after establishing a VPC peering connection, you must update the route tables in both VPCs. Without a route in VPC A pointing to VPC B’s CIDR through the peering connection, and vice-versa, traffic won’t flow. It’s like having a direct cable but no instructions on how to send data over it.

The next step is usually understanding how to control what traffic can flow between these connected networks, which leads to Security Groups and Network Access Control Lists (NACLs).

Want structured learning?

Take the full Computer Networking course →