Worked Example - Build a Three-Tier VPC via API
This page shows the API calls required to build a three-tier VPC with an internet-facing load balancer, DNS, and DHCP, in the order they must be issued.
Five of the calls depend on behaviour that is not obvious from the individual endpoint pages. Each of those is called out inline so the sequence can be followed end-to-end without discovering a dependency by trial.
Prerequisites
Karios control plane reachable at
https://<mgmt>/api/v2.A valid Bearer token (see API Reference under the user-authentication tag).
For VXLAN: a fabric registered via
POST /controlnode/fabric-config. Creating the VXLAN physical network needs no more than that; the VXLAN guest networks, VPC tiers and VM deploys later in this sequence also need the fabric to be converged (see Fabric readiness gates guest networks, tiers and VMs - not physical networks).
Sequence
Thirteen calls, in this order. All bodies and response shapes are documented per-endpoint in the API Reference; this page names the calls and the ordering constraints between them.
# |
Call |
Ordering note |
|---|---|---|
1 |
|
Precondition. A |
2 |
|
Returns the offering used in step 4. See
Isolation mode is carried in the offering name suffix about isolation mode being
carried in the composed name suffix. Pass
|
3 |
|
Required in practice: every Karios VPC tier offering
sets |
4 |
|
Redundancy is not chosen here - |
5 |
|
One per tier. |
6 |
|
Set |
7 |
|
One per tier. Waits on the VPC’s virtual router being up. |
8 |
|
Use this path to allocate the address, not
|
9 |
|
Always pass |
10 |
|
Rule first, then membership. Read membership back with
|
11 |
|
Standard. |
12 |
|
DHCP scope creation is independent of the network - pass
|
13 |
|
Poll until every node reports |
Caveats you cannot derive from the reference alone
Fabric readiness gates guest networks, tiers and VMs - not physical networks
Creating a VXLAN physical network requires only that a fabric is
registered at all - GET /controlnode/fabric-config returning 204 No
Content means it is not, and that is the single state which refuses the
create (with 412 Precondition Failed). A rollout that is still pending or
rolling out, or that has finished failed or degraded, is deliberately
allowed: the physical network is only CloudStack metadata and no overlay
traffic rides it yet, and physical networks are created during cluster
bring-up, before the fabric converges.
The strict gate applies to the later calls that do put traffic on the overlay - VXLAN guest-network creation, VPC tier creation (step 7), and deploying a VM onto a VXLAN network (network update and restart are gated the same way). Those require all of:
rollout_status: ready,a settled MTU rollout - an MTU rollout still in flight blocks them,
every fabric node healthy: one node reporting
failedorunreachableblocks new VXLAN creates cluster-wide until it converges.
Failures here are runtime errors, and all of them are retriable once the fabric converges.
Isolation mode is carried in the offering name suffix
/network/vpc-offerings/ensure-for-size returns an offering whose composed
name (for example karios-vpc-vxlan-medium-redundant) carries the isolation
decision (vlan vs vxlan). This drives Karios-layer pairing validation
when tiers are later created against it. Renaming a composed offering breaks
pairing silently.
Redundancy is chosen at the offering, not on the VPC
Pass redundant_router: true to step 2
(/network/vpc-offerings/ensure-for-size). That composes the
-redundant variant of the offering (for example
karios-vpc-vxlan-medium-redundant), which carries the redundant-router
capability, and the VPC created from it in step 4 is redundant from birth.
/network/vpcs still accepts a redundant_vr field, but it is legacy:
the create path does not read it. Sending it changes nothing and reports
nothing - the response looks identical and the VPC comes up with a single
router. Decide redundancy in step 2.
Do not try to promote an existing VPC afterwards by restarting it with
CloudStack’s make-redundant option either: that moves the VPC onto
CloudStack’s own redundant VPC offering and discards the composed Karios
offering name that tier pairing keys on (see
Isolation mode is carried in the offering name suffix). Recreate the VPC from a -redundant
offering instead.
ACL rule order must be set explicitly
/network/vpcs/acl-lists/items accepts number as the rule ordering
key. Omit it and CloudStack picks one for you, from the highest number
currently in the list - so two rules created in parallel both read the same
“highest” value and race for the slot that follows it. Nothing in the Karios
layer de-conflicts this: number is forwarded to CloudStack exactly as
sent, and is only omitted from the call when you omit it. The resulting rule
order follows arrival order, which for a security ACL is a policy bug, not a
display glitch.
Set number explicitly on every rule, and reject the call locally if two
of your own rules would collide. Numbering in steps of ten (100, 110, 120)
leaves room to insert rules later without renumbering the list.
The DDI path is the only one that can write DNS - and only if you ask
Three surfaces can allocate a public address:
/network/public-ip-addresses, /ddi/public-ips, and
/network/vpcs/public-ips/acquire. All three perform the same underlying
CloudStack address association, so the address itself is identical whichever
you use.
/ddi/public-ips is the only one that can also create the matching DNS and
PTR records - but it does not do so by default. Those fields are optional and
unset unless you send them:
POST /ddi/public-ips
{
"zone_id": "<zone-uuid>",
"network_id": "<network-uuid>",
"create_dns": true,
"hostname": "lb-01",
"dns_zone": "example.com",
"create_ptr": true
}
Called with only zone_id and network_id, this endpoint creates no DNS
record and no PTR record - the same outcome as the other two paths, with no
error to tell you so. A DNS failure is non-fatal too: the address stays
allocated and the failure is reported in the response message rather than as
an error status, so check the response, not just the status code.
IPAM works the other way round. The two /network/... paths record the
address in Karios IPAM as part of the call; /ddi/public-ips does not, and
an address allocated there is picked up only by the background CloudStack to
IPAM reconciliation.