A VPC is a routed multi-tier network. Where a Guest network is one flat subnet, a VPC carves your IP range into multiple tiers (subnets), each with its own subnet-level firewall — a Network ACL. Use a VPC when you want to keep web servers, app servers, and databases on separate subnets that can talk to each other under explicit rules.
Anatomy
- Super CIDR. The whole VPC’s IP range — typically a
/16like10.0.0.0/16. Every tier you create lives inside this range. - Tier. A subnet inside the VPC, e.g.
10.0.1.0/24for web,10.0.2.0/24for app. Each tier has its own ACL. - Virtual Router (VR). A system-managed appliance at the first usable IP in each tier (e.g.
10.0.1.1). Handles DHCP, NAT, port forwarding, VPN. - Public IPs. Acquired at the VPC level (not the tier level), then forwarded to specific instances.
Create a VPC and two tiers
A worked example: a public web tier and a private DB tier. The web tier accepts HTTP from the internet; the DB tier only accepts traffic from the web tier.
CLI
ZONE=$(cmk list zones name=is1 | jq -r '.zone[0].id')
VPCOFF=$(cmk list vpcofferings name="Default VPC offering" | jq -r '.vpcoffering[0].id')
# 1. Create the VPC shell
VPC=$(cmk create vpc name=demo cidr=10.0.0.0/16 vpcofferingid=$VPCOFF zoneid=$ZONE | jq -r '.vpc.id')
# 2. Make an ACL list and a tier for each subnet
NETOFF=$(cmk list networkofferings name=DefaultIsolatedNetworkOfferingForVpcNetworks | jq -r '.networkoffering[0].id')
WEB_ACL=$(cmk create networkacllist name=web vpcid=$VPC | jq -r '.networkacllist.id')
DB_ACL=$(cmk create networkacllist name=db vpcid=$VPC | jq -r '.networkacllist.id')
cmk create network name=web vpcid=$VPC \
gateway=10.0.1.1 netmask=255.255.255.0 \
networkofferingid=$NETOFF zoneid=$ZONE aclid=$WEB_ACL
cmk create network name=db vpcid=$VPC \
gateway=10.0.2.1 netmask=255.255.255.0 \
networkofferingid=$NETOFF zoneid=$ZONE aclid=$DB_ACLNow add ACL rules — web allows HTTP from anywhere, DB allows port 5432 only from the web subnet:
# Web: allow inbound TCP 80 from 0.0.0.0/0
cmk create networkacl aclid=$WEB_ACL number=100 protocol=tcp \
startport=80 endport=80 cidrlist=0.0.0.0/0 action=allow traffictype=ingress
# DB: allow inbound TCP 5432 from the web tier CIDR only
cmk create networkacl aclid=$DB_ACL number=100 protocol=tcp \
startport=5432 endport=5432 cidrlist=10.0.1.0/24 action=allow traffictype=ingress
# Both tiers: allow egress on ephemeral ports (stateless ACLs need return paths explicitly)
cmk create networkacl aclid=$WEB_ACL number=200 protocol=tcp \
startport=1024 endport=65535 cidrlist=0.0.0.0/0 action=allow traffictype=egress
cmk create networkacl aclid=$DB_ACL number=200 protocol=tcp \
startport=1024 endport=65535 cidrlist=0.0.0.0/0 action=allow traffictype=egressSee Network ACLs for why the egress rule is needed (ACLs are stateless — return traffic needs an explicit hole).
Console
Network → VPC → Add VPC, fill in the form. Once the VPC exists, click into it and use the Tiers (or Networks) tab to add web and db subnets with their own ACL lists.
Public IPs on a VPC
Public IPs are acquired at the VPC level — not per tier. Once allocated, you can forward ports to instances in any tier of the VPC. See Public IPs.
Connecting on-premises
A VPC can terminate an IPsec site-to-site VPN to your on-prem network. See Site-to-site VPN.
Common failures
- Tier doesn’t get DHCP. The Virtual Router for that tier failed to start. Stop and restart the VPC’s VR via Network → VPC → your VPC → Virtual Router → Stop / Start.
- DB tier can’t reach the web tier. Stateless ACLs — both directions must be allowed. Add an egress rule on the DB tier and an egress on the web tier for the return path.
- Public IP can’t be acquired. Confirm you’re on the VPC view, not the Guest Network view — the Acquire button on Guest networks doesn’t apply.