On this page
Azure credit gate
Before the Azure provider creates or starts a VM, Stado holds the operation to the operator's credit floor. The billing reading this gate shares is described on Costs and budgets.
The floor
The floor is the operator's own ruling, kept in Oko's register with his words:
capability:cloud@credits-floor:azure:<amount>:<currency> (oko rulings list --json; Tama reads the same ruling and checks the amount against what
he said). Stado keeps no number of its own for it. Several standing floors for
Azure in one currency decide by the highest; floors in different currencies
cannot be compared, so the operation is refused naming both rulings: the
operator says which floor stands, and his later words supersede the other once
oko rulings supersede has read them (oko rulings show <id> then names
superseded_by), or a floor bound to a ruling by mistake is taken off it with
oko rulings unbind <id> --subject capability:cloud@credits-floor:azure:<amount>:<currency>. An amount that is
not a finite number at or above zero is refused with its ruling's id, and a
floor not in USD, the currency Azure's machine prices are quoted in, is
refused because an hour of a machine cannot be taken from it; stado billing show's provision_gate reads the same floor through the same check, so it
never admits what a create or start refuses.
The check before a create or start
Immediately before the Azure provider creates or
starts a VM it reads that floor, reads the balance through the same Skarbiec
azure-billing principal and ARM call as stado billing show, prices the
machine's size from the Azure Retail Prices API at the highest on-demand USD
hourly rate any configured location (AZURE_LOCATIONS) quotes for it as a
Linux VM (a product named Virtual Machines …; the same size's Cloud
Services role and Windows licences price something else), and
refuses the operation unless the balance less that one hour stays above the
floor: creating Azure VM <name> is refused: the Azure credit balance <balance> USD less one hour of <size> (<hourly> USD, <sku> in <region>, Azure Retail Prices API at <time>) is not above the floor <amount> <currency> (the operator's ruling <id>: "<his words>"); how long the machine would run is not known when it starts. A start reads the stopped VM's
hardwareProfile.vmSize (a GET that costs nothing) to price it; starting Azure VM <name> is refused: … names the same parts.
The balance of a grant Azure does not report
A sponsorship grant's credits balance call answers HTTP 204 with no body,
so the balance is not reported. The billing property still states the grant:
its amount, start date and type (grant_amount, grant_start_date,
grant_type). The reading then takes the balance as the grant less the
subscription's actual cost since the grant began. That cost comes from a Cost
Management query (ActualCost, from the grant's start to the moment of
reading, summed), at the configured subscription_id. available_balance is
that difference, currency is the grant's currency (the cost's, when the
grant names none), and balance_source names both sources:
{"grant", "actual_cost_since_grant", "from", "to", "cost_scope"}. Cost
Management throttles its query API: an HTTP 429 names how long to wait in its
x-ms-ratelimit-…-retry-after headers or Retry-After, and the reading holds
the longest of them (announced as a czekam wait) and asks again; a 429 that
names no wait is a query that did not answer. A cost in
another currency than the grant's, a query that does not answer, and a grant
with no amount or start leave available_balance null, with
balance_source.unread saying why, and every create or start is refused as a
balance that cannot be read. A reported balance keeps balance_source: "credits balance". credit_used is the grant less the available balance
either way.
Refusals
His rule is that Azure work runs only while its credits stay above the floor
he names, so with no standing floor ruling nothing shows the credits suffice
and every create or start is refused, saying so: … is refused: no standing ruling of the operator names an Azure credit floor (capability:cloud@credits-floor:azure:<amount>:<currency> in Oko's register), so nothing shows the credits suffice; his rule is that Azure work runs only while its credits stay above the floor he names; record his words naming it with oko rulings record --subject
capability:cloud@credits-floor:azure:… they cannot be compared) or than USD, in which machine prices are
quoted, is refused, as are a balance that cannot be read (the section's status
and cause), an ok section with no available_balance or currency, a size no
price quotes (no on-demand USD hourly price quotes <size> …, so its cost is not known) and a VM with no size. An unknown balance, cost or floor is never
read as safe. How long a machine runs is not known when it starts, so the
first hour is the cost the gate can know.
Machines already running are not stopped by the gate or by any billing read: stopping running work is cycling it, which needs Oko's admission or a ruling of the operator naming it. The floor refuses new creates and starts. Deleting or stopping a VM is never gated, because both end spending.
What the billing reading publishes
The collector writes the balance-against-floor part of the decision on the
Azure section it publishes, as provision_gate: admits, floor
({"amount", "currency", "ruling", "said"}, absent when no floor ruling could
be read), refusal when it does not admit, and perStart, which says that
each create or start also prices one hour of its machine. stado billing show prints it as Azure provisioning gate: the balance is above the floor <amount> <currency> (the operator's ruling <id>: "<his words>"); each create or start also prices … or Azure provisioning gate: <refusal>; a document
written before the gate existed says it carries no gate decision and that
stado billing refresh writes one. Stado Desktop → Compute providers → "Read
provider credit, and whether the Azure credit gate admits a VM create or
start" runs the same reading.
Source: this website