Two VPCs whose CIDR ranges overlap cannot be peered, and a subnet that overlaps its own VPC's other subnets will be rejected outright. Given the address plan for a cluster, find every colliding pair before Terraform does.
Every CIDR block is a contiguous, power-of-two-sized range of 32-bit integers. Convert each block to [low, high]:
size = 2 ** (32 - prefix)
network = ip - (ip % size) # clear the host bits
low, high = network, network + size - 1
Two ranges overlap when low_i <= high_j and low_j <= high_i. That single test covers all three cases that matter: partial overlap, one block fully containing another (10.0.0.0/16 and 10.0.1.0/24), and two identical blocks.
Comparing the strings, or only comparing prefixes, misses containment — which is the case that actually shows up in a VPC plan.
Note the input may carry host bits (10.0.5.7/24 means the block 10.0.5.0/24), so normalise before comparing.
Implement:
def find_overlaps(cidrs):
Return a list of [cidrs[i], cidrs[j]] pairs with i < j, in increasing order of i then j, for every overlapping pair. Return [] when the plan is clean.
print(find_overlaps(["10.0.0.0/16", "10.0.1.0/24", "10.1.0.0/16", "192.168.0.0/16"]))
Output:
[['10.0.0.0/16', '10.0.1.0/24']]
10.0.1.0/24 sits entirely inside 10.0.0.0/16, so the pair collides; the other two blocks are disjoint from everything.
print(find_overlaps(["10.0.0.0/16", "10.0.1.0/24", "10.1.0.0/16", "192.168.0.0/16"]))
[['10.0.0.0/16', '10.0.1.0/24']]
As integer ranges, 10.0.0.0/16 covers 10.0.0.0-10.0.255.255 and 10.0.1.0/24 covers 10.0.1.0-10.0.1.255, which lies wholly inside it, so low_i <= high_j and low_j <= high_i holds. 10.1.0.0/16 starts above the first block's last address and 192.168.0.0/16 is far away, so neither collides.
[cidrs[i], cidrs[j]] with i < j, ordered by i then j