Network Topology
Simulate real network reachability across VPCs, peering, security groups, ACLs, and routes so you can test connectivity logic without a cloud
Network Topology
cloudemu can evaluate actual network reachability between your emulated resources. It reads the compute, networking, and DNS drivers and answers three questions the way a real cloud network would: can these two instances talk?, what path does traffic take?, and what does this hostname resolve to?
This lets you unit-test firewall rules, security-group changes, routing, and DNS wiring deterministically — no VPCs to stand up, no cloud account.
import (
"github.com/stackshy/cloudemu"
"github.com/stackshy/cloudemu/topology"
)
cloud := cloudemu.NewAWS()
engine := topology.New(cloud.EC2, cloud.VPC, cloud.Route53)
res, _ := engine.CanConnect(ctx, topology.ConnectivityQuery{
SrcInstanceID: "i-web",
DstInstanceID: "i-db",
Port: 5432,
Protocol: "tcp",
})
if !res.Allowed {
// res.Reason explains why — e.g. "no security-group rule permits tcp/5432"
}The engine consumes the same driver instances your app already uses, so it sees exactly the VPCs, subnets, security groups, route tables, peering connections, and DNS records you created.
What it evaluates
topology.New(compute, networking, dns) returns an *Engine with three methods:
CanConnect
res, err := engine.CanConnect(ctx, topology.ConnectivityQuery{
SrcInstanceID: "i-web",
DstInstanceID: "i-db",
Port: 5432,
Protocol: "tcp", // "tcp", "udp", "icmp", or "-1" (all)
})Decides whether two instances can communicate on a port/protocol, accounting for VPC membership, VPC peering, security-group ingress/egress rules, and network ACLs. The ConnectivityResult carries:
Allowed bool— the verdictReason string— a human-readable explanationPath []RouteHop— the hops traffic would takeSGVerdict— the security-group match detailACLVerdict— the network-ACL decision (if any)
TraceRoute
hops, err := engine.TraceRoute(ctx, "i-web", "8.8.8.8")Returns the network path from an instance to a destination IP as a slice of RouteHop{Type, ResourceID, Detail}, where Type is one of instance, subnet, route-table, gateway, nat-gateway, peering, or local. Route-table lookups and CIDR matching decide whether traffic exits via an internet gateway, a NAT gateway, a peering connection, or is blocked.
Resolve
ips, err := engine.Resolve(ctx, "service.internal")Walks the DNS zones and returns the resolved values for a hostname (A, AAAA, CNAME records), or nil if there's no match.
Why it's a driver consumer
Topology sits on top of the driver layer, the same as the Chaos engine. Because it reads live driver state rather than a static config, connectivity answers always reflect the resources currently in your emulated cloud — create a security-group rule and CanConnect sees it on the next call, with no re-wiring.