---
title: 'Cloud Networking Concepts'
source: 'https://academia.sh/en/courses/network-operations/cloud-networking-concepts'
course: 'Network Operations and Automation'
language: en
updated: '2026-08-17T18:07:14+00:00'
license: 'CC BY-SA 4.0'
---

# Cloud Networking Concepts

Virtual network, subnet, security group, and gateway all fall under the same lever-tail measure: when a single subnet prefix length is applied to forty subnets, /26 leaves seventeen short, while /25, which closes the tail, does not fit the virtual network's block.

The previous lesson applied a single template to forty devices and counted the deviated
minority. In every measurement in the course up to this point, the subject was the same kind: **a
device we own**. It sat on a rack, had a serial number, could be reached through a shell, and got
replaced when it broke. The lever touched this device.

This lesson's question changes the subject: what if the subject is an object **we do not own**?
In cloud networking, the virtual network, subnet, security group, and gateway are not devices;
they are **configuration records**. There is no box to touch, no shell to open, no light to check
at the moment of failure. The question is: when the subject turns into a record, does the
lever-tail measure change?

## The Subject That Becomes a Record

Cloud service models, the shared responsibility boundary, and provider selection were established
in the Cloud Computing curriculum's Compute and Networking in the Cloud course; that narrative is
not repeated here. This lesson takes up the cloud object from a single angle: **as the
measurement's subject**.

A subject that turns into a record gains three things. It is created and destroyed instantly; a
single request can take its count from forty to four hundred. Its definition is text, so it
enters version control and can be copied identically elsewhere. Third, its creation is always the
same: the same definition produces the same object every time.

What it loses is also three things, and this is the part that concerns the measurement. We cannot
see the physical path underneath the object. We do not set the object's limits — how many
subnets a virtual network can carry, how many rules a security group can hold, are numbers handed
to us. And once an object is created, **some of its fields cannot be changed**: a virtual
network's address block cannot be grown in place after it is set up.

This third one directly creates the lever. An unchangeable field is a decision made once, for
everyone. If all forty subnets sit inside the same virtual network, that virtual network's block
is the common limit of all forty subjects.

## Four Objects

Cloud networking's core comes down to four classes. The transcript below is not a call; it shows
the shape of the objects' declarative definition and is not run.

```text
# taught object transcript, not run

virtual network:
  name: measurement-net
  block: 10.40.0.0/20        # cannot be changed after creation
  region: region-1

subnet:
  name: measurement-01
  virtual network: measurement-net
  block: 10.40.0.0/26        # cut from the virtual network's block
  reserved addresses: 5      # network, broadcast, gateway, and two service addresses
  route table: measurement-default

security group:
  name: measurement-device
  ingress:
    - source: security group measurement-collector
      port: 443/tcp
    - source: 10.40.0.0/20
      port: 22/tcp
  egress:
    - destination: anywhere
      port: 443/tcp

gateway:
  - type: egress-only        # inside goes out, no inbound from outside
  - type: peering            # a direct path to another virtual network
    peer: management-net
```

A **virtual network** is an address space and an isolation boundary. A **subnet** is a slice of
that space and carries its own route table. A **security group** is a rule sequence attached not
to a device but to a set of interfaces. A **gateway** is the object that establishes the virtual
network's relationship with the outside; its type determines direction.

In the security group's first rule, the source is not an address block, it is **another security
group**. This is cloud networking's one genuinely original structural contribution: the rule
binds to a **label** instead of an address, and rewriting the rule is not needed when the address
changes. This lesson takes the security group only as a **configuration object**; the rule
sequence's intent-versus-actual gap was measured in the Wireless Networks and Network Security
course and is not repeated here.

## Public and Private Subnet

The most commonly misunderstood thing about subnets is where their being **public** or
**private** comes from. It does not come from the address block. Whatever a subnet's block is,
the only thing that makes it reachable from outside is its **route table**: if the table has a
default route to an outbound gateway, the subnet is public, if not, private. Two subnets inside
the same virtual network can carry neighboring address blocks and have completely different
access properties.

This makes the route table a second lever, and it produces a different tail from the first. The
table attaches not to a subnet but to a **set of subnets**; adding a route to the table adds it to
every subnet sharing it at once. The subnets where the route is unnecessary form the tail, and
this tail is entirely **silent**: an extra route produces no error, creates no latency, writes no
log entry. It only silently widens the set of places that subnet can reach.

Which table a subnet is attached to is therefore a decision independent of the address plan, and
it has to be counted separately. If it is not known how many of the forty subnets share the same
table, it is also not known how many subjects a single route row touches. **Narrowing:** the
table is split by access property — outbound subnets share one table, non-outbound share another,
and the default route is written only into the first.

This lesson's measurement does not touch the second lever; the only thing measured is the address
block. The two need to be kept separate, because even though they operate on the same subnet
object, they leave different tails: one is failing to fit endpoints, the other is unnecessary
access.

## The Lever: A Single Prefix Length

Forty subnets are to be opened. How many endpoints each will carry differs from one to the next.
The operator is handed a single number: **the subnets' prefix length**. This number is chosen
once and applied to all forty of the forty subnets at once.

Why a single number? Because choosing forty separate prefixes means forty separate decisions, and
every one of those decisions has to be reviewed, documented, and remembered later. A single
prefix gives a single decision: which block a subnet falls into is found by arithmetic, the plan
fits in one table, route summarization is written in a single row — this is the gain established
in the Switching and Routing course's Address and Naming Plan lesson.

One detail here departs from the Network Models and Protocols course's subnet arithmetic. There,
the count of addresses reserved per subnet was two — the network address and the broadcast
address. In a cloud virtual network, this count is **five**: the gateway and two service addresses
also sit in the block and can never be handed to an endpoint. In small blocks, this difference is
decisive; **five** of the `/27` block's thirty-two addresses are gone from the start.

The measurement probes two limits at once. A subnet's block must meet its endpoint demand. And
the sum of the forty blocks must fit inside the virtual network's block. The two limits pull in
opposite directions: shrinking the prefix solves the first and breaks the second.

The assumptions the measurement rests on:

- **AC61** — The forty subjects are the course's fixed set; each subject corresponds to a
  subnet, and the subject's capacity is read as that subnet's **endpoint count**. The set is not
  changed.
- **AC62** — The virtual network's block is `/20`, that is **4096** addresses, and it cannot be
  grown after creation.
- **AC63** — Every subnet has **5** unusable addresses: the network address, the broadcast
  address, the gateway, and two service addresses. Usable endpoint count is what remains after
  subtracting these five from the block size.
- **AC64** — The oracle is the setup itself: we know every subnet's actual endpoint demand
  because we wrote it. The plan does not use this information, it only applies the single
  prefix.
- **AC65** — The measurement is not a cloud call; no object is created, no request is sent to any
  provider. What is counted is address arithmetic.
- **AC66** — The comparison row, the per-subject plan, is the absence of the lever: every subnet
  gets the smallest block that covers its own demand, and the decision count is forty.

## The Measurement

```python
"""Cloud networking: a single subnet prefix length applied to forty subnets at once.

Lever      - the single prefix length used across all of the virtual network's subnets.
Tail       - a subnet whose block does not meet its demand.
Invisible  - the address sitting idle inside subnets.
"""
SEED = 20260812
VPC_PREFIX = 20      # the virtual network's address block
RESERVED = 5          # addresses unusable in every subnet


def make_rng(seed):
    d = seed % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def subjects(count=40, seed=SEED):
    r, out = make_rng(seed), []
    for i in range(count):
        out.append({
            "no": i + 1,
            "capacity": 20 + r(81),
            "latency": 5 + r(45),
            "class": ("interactive", "batch", "standby")[r(3)],
            "special": r(9) == 0,
        })
    return out


def block_size(prefix):
    return 1 << (32 - prefix)


def single_prefix(subj, prefix):
    """A single prefix is applied to forty subnets; demand is measured by endpoint count."""
    usable = block_size(prefix) - RESERVED
    short = missing = idle = 0
    for o in subj:
        gap = o["capacity"] - usable
        if gap > 0:
            short += 1
            missing += gap
        else:
            idle -= gap
    return usable, short, missing, idle, block_size(prefix) * len(subj)


def per_subject_prefix(o):
    """The prefix of the smallest block that covers one subject."""
    prefix = 32
    while block_size(prefix) - RESERVED < o["capacity"]:
        prefix -= 1
    return prefix


subj = subjects()
vpc = block_size(VPC_PREFIX)
print(f"virtual network /{VPC_PREFIX} = {vpc} addresses | subnets {len(subj)} | "
      f"endpoint demand {min(o['capacity'] for o in subj)}-{max(o['capacity'] for o in subj)} "
      f"| total demand {sum(o['capacity'] for o in subj)}")
print()
print(f"{'prefix':>7s} {'usable':>14s} {'short':>9s} {'missing':>9s} "
      f"{'idle addresses':>14s} {'addresses needed':>16s} {'fits vpc':>10s}")
for prefix in (27, 26, 25, 24):
    u, s, m, i, g = single_prefix(subj, prefix)
    print(f"  /{prefix:<4d} {u:14d} {s:9d} {m:9d} {i:14d} {g:16d} "
          f"{'fits' if g <= vpc else 'does not fit':>10s}")

total = idle = 0
for o in subj:
    prefix = per_subject_prefix(o)
    total += block_size(prefix)
    idle += block_size(prefix) - RESERVED - o["capacity"]
print(f"  {'per subject':<12s} {'-':>9s} {0:9d} {0:9d} {idle:14d} {total:16d} "
      f"{'fits' if total <= vpc else 'does not fit':>10s}")
print()
spread = {}
for o in subj:
    spread[per_subject_prefix(o)] = spread.get(per_subject_prefix(o), 0) + 1
print("distinct prefixes in the per-subject plan:", len(spread),
      "-", {f"/{k}": v for k, v in sorted(spread.items())})
```

```
virtual network /20 = 4096 addresses | subnets 40 | endpoint demand 22-99 | total demand 2336

 prefix         usable     short   missing idle addresses addresses needed   fits vpc
  /27               27        36      1265              9             1280       fits
  /26               59        17       371            395             2560       fits
  /25              123         0         0           2584             5120 does not fit
  /24              251         0         0           7704            10240 does not fit
  per subject          -         0         0            984             3520       fits

distinct prefixes in the per-subject plan: 3 - {'/25': 17, '/26': 19, '/27': 4}
```

## Where the Tail Moved

The four rows show four settings of a single lever, and none of them is clean.

The `/27` block leaves **36** of forty subnets short; missing endpoints total **1265**. Idle
addresses, in contrast, are only **9** — the plan is tight, because it hands almost no subnet
extra addresses. The cost of tightness is a tail of thirty-six out of forty.

`/26` brings the tail down to **17** and missing endpoints to **371**. Idle addresses climb from
**9** to **395**. Growing the lever one step melted the tail by more than half, but seventeen of
forty subnets still cannot meet their demand.

`/25` brings the tail to **0**. All forty of forty subnets meet their demand, no missing
endpoints. And right on this row, the right-hand column takes over: this plan wants **5120**
addresses, and the virtual network's block is **4096**. The plan **does not fit** the virtual
network. `/24` does the same thing more heavily: **10240** addresses, **7704** idle.

The tail did not disappear. **It moved from the subnet to the virtual network.** At `/26`,
seventeen subnets fell short; at `/25`, no subnet falls short, but the virtual network itself
falls short — and per **AC62**, the virtual network's block cannot be grown. The tail's new name
is no longer "seventeen subjects," it is "the entire deployment." Growing the lever did not
remove the tail, it changed **who is in it**.

## The Idle Address

An indicator that counts only subnets that do not fit reads the `/25` row as **flawless**: zero
tail. On that row, **2584** addresses sit unassigned to any endpoint — half of the **5120**
addresses the plan wants. The same indicator reads the `/27` row as the worst, even though idle
addresses there are only **9**.

The two numbers exist at once, and a single indicator cannot see both. This is the fourth reading
counted across the course: **an indicator that counts overflow does not see the gap.** In address
planning, the gap is especially costly precisely because it is invisible — it produces no
warning, writes no log entry, and is only noticed when a new subnet can no longer be added to the
virtual network.

The last row states what the lever itself costs. When every subnet is given its own prefix, the
tail is **0**, idle addresses **984**, addresses needed **3520**, and the plan fits the virtual
network. So a correct answer exists; it cannot be expressed with a single number. Its cost
is written in the last row: the plan carries **three** separate prefixes, requires **forty**
separate decisions, and breaks single-row route summarization. The lever's tail exists for
exactly this reason: because the cost of forty decisions was judged greater than the cost of the
tail.

## Security Group and Gateway

The remaining two objects are two more faces of the same pattern, and they are not measured in
this lesson; each gives rise to its own tail.

**A security group** is a rule sequence, and a single group attaches to many interfaces. Widening
one of the group's rules widens it on every interface it is attached to at once. **Narrowing:**
binding the rule's source to another security group instead of an address restrains this
widening: the rule is now bound to a **membership**, not an address range, and the membership
list updates together with object lifecycle. How many interfaces the group is attached to still
has to be counted separately; without that count, how many subjects a rule touches is unknown.

**A gateway** is the object that establishes the virtual network's relationship with the outside,
and its type determines direction: some gateways permit only inside-to-outside traffic, some open
a two-way path, and some match only a specific peer network. Direction here is a **security**
property, not a performance one. Because an egress-only gateway is one-directional, no inbound
connection exists; creating a two-way gateway removes this restriction, and the moment it is
removed, it is removed for every subnet in the virtual network. **Narrowing:** the gateway is
written only into the route table of the subnets that need it — even if the gateway exists at the
virtual-network level, a subnet with no route to it cannot pass through it.

## Summary

- Cloud networking's objects are configuration records, not devices; they are created instantly,
  but some of their fields — like the virtual network's block — cannot be changed after creation,
  and that field becomes forty subjects' common limit.
- A single subnet prefix length is a lever: `/27` leaves **36** of forty subnets below their
  demand, `/26` leaves **17**.
- The `/25` plan that zeroes the tail wants **5120** addresses, and the virtual network's block
  is **4096**; the tail does not disappear, it moves from the subnet to the virtual network.
- Idle addresses are a separate number: **2584** at `/25`, **9** at `/27`. An indicator that
  counts only what does not fit cannot see this difference.
- Giving every subnet its own prefix brings the tail to **0** and idle addresses to **984**, but
  it brings three separate prefixes and forty separate decisions; the lever exists for exactly
  the purpose of not making these forty decisions.

## Next Step

This entire lesson's measurement stayed inside a single virtual network: forty subnets cut from
the same block, sharing the same gateways, subject to the same lever. But the reason cloud
objects exist is most often that they work together with a network we own, and that network is
somewhere else. The next lesson measures the options that connect two networks: what a
site-to-site tunnel built over a shared path gives which subject, versus a dedicated link giving
a separated path, and when the two are used together, which class the tail collects on.
