organization_budget — version 2.0
Source: presets
Purpose
Budgets on the infrastructure billing account with alert thresholds: one for the whole
account, and one per entry of budgets for a set of projects or folders.
WHAT AN ENTRY IS. { name amount }, and optionally projects, folders, email and
import_id. The first entry of budgets is the organisation's budget, global-budget,
built from budget_amount and budget_notification_email. Binding budgets in the
estate replaces the whole list, so an estate that adds budgets writes that entry too;
a project asks for its own with contributes_budgets, checked by satz check-request.
WHAT A BUDGET COUNTS. An entry with neither projects nor folders counts the whole
billing account. projects lists projects/<number> — the project NUMBER:
"projects for a project the estate declares.
folders lists folders/<id> or organizations/<id>; google_folder.<label>.name
already has that form. A budget lives on the billing account whatever it counts, so a
project billed to another account is not counted here.
WHO IS TOLD. The billing account's administrators and users get every alert by e-mail
from Google, with no resource — the group presets
grants roles/billing.admin. An entry with an email also gets an e-mail notification
channel in budget_channel_project (the infrastructure project), named in its budget;
no Pub/Sub is involved. budget stops the mails to the billing
account's administrators and users for the budgets that have a channel; a budget without
one keeps them, so no budget alerts nobody.
ADOPTING AN EXISTING BUDGET. Give its entry import_id = "billingAccounts/<account>/ budgets/<id>" (gcloud billing budgets list --billing-account=<account>); satz adopt
does not resolve budgets. An empty import_id creates the budget.
Use it
params {
// the pack's own defaults — copy only the lines you change
budget_amount = "1000"
budget_currency = "EUR"
budget_threshold_rules = [
{ threshold_percent = 0.5 spend_basis = "CURRENT_SPEND" },
{ threshold_percent = 0.8 spend_basis = "CURRENT_SPEND" },
{ threshold_percent = 1.0 spend_basis = "CURRENT_SPEND" },
]
budget_notification_email = ""
budget_default_recipients_off = false
budget_channel_project = infra_project_name
budgets = [ { name = "global-budget" amount = budget_amount } ]
}
use "presets/organization-budget.satz"
Needs from outside the pack:
billing_account_infra— declared byestate_core; use one of them alongside, or declare it in the estate.infra_project_name— declared byestate_core; use one of them alongside, or declare it in the estate.
Params
| param | default |
|---|---|
budget_amount |
"1000" |
budget_currency |
"EUR" |
budget_threshold_rules |
[ { threshold_percent = 0.5 spend_basis = "CURRENT_SPEND" }, { threshold_percent = 0.8 spend_basis = "CURRENT_SPEND" }, { threshold_percent = 1.0 spend_basis = "CURRENT_SPEND" } ] |
budget_notification_email |
"" |
budget |
false |
budget_channel_project |
infra_project_name |
budgets |
[ { name = "global-budget" amount = budget_amount } ] |
Questions
What to ask before this pack is configured, and what changing the answer costs.
| asks about | prompt | reversal | blast | recommends |
|---|---|---|---|---|
budget_amount |
The organisation budget's amount per calendar month, in whole units of the billing account's currency | edit | none | — |
budget_currency |
The billing account's currency (ISO 4217, for example EUR or USD) | edit | none | — |
budget_notification_email |
An address that gets the budget alerts beside the billing account's administrators — a group's address, never a person's | edit | none | — |
budget |
Stop mailing the billing account's administrators and users for the budgets that have an address of their own? | edit | none | — |
budget_amount — Alerts go out at 50, 80 and 100 % of it. Too high and the alarm comes after the money is gone; too low and the alerts are noise nobody reads.
budget_currency — A budget is stated in the billing account's own currency; any other is refused when the budget is created.
budget_notification_email — Google mails the billing account's administrators and users on its own. An address here adds an e-mail notification channel, for a team that holds no billing role.
An empty answer, "", is an answer: the billing account's administrators and users alone.
budget_default_recipients_off — A project's budget then reaches the project's team alone. A budget without an address keeps mailing the administrators, so no budget alerts nobody.
Contributes
| resource type | labels |
|---|---|
google_billing_budget |
one per entry of budgets, by name, one per entry of budgets, by name |
google |
one per entry of budgets, by name |
Requests
What a project may add to this pack's lists, through contributes_<param> in a file the estate uses after a reviewed pull request; satz check-request checks such a file.
| list | key | fields | description |
|---|---|---|---|
budgets |
name |
name matching [a-z][a-z0-9-]*, amount matching [0-9]+, projects, folders, email matching ([^@: ]+@[^@: ]+)?, import_id |
A budget: its name, its monthly amount, the projects (projects/<number>) or folders (folders/<id>) it counts, and the address its alerts go to |
Claims
None — this pack proves no control by itself.
History
| version | date | change |
|---|---|---|
| 2.0 | 2026-10-02 | amount, currency, thresholds and recipients are params, budget_amount and the recipients asked; budgets adds budgets for projects or folders, each with an optional e-mail channel, as a request point; an existing budget is adopted through an entry's import_id, the placeholder id is gone |
| 1.0 | 2026-08-20 | organization budget with threshold alerts ("import-id" example) |
The whole library's history: the changelog in presets/CHANGELOG.md.
Notes
The "import-id" in the pack is a placeholder for adopting a budget that already exists — satz adopt does not resolve budgets, so the id is filled by hand. Delete the line for a fresh budget, or the apply tries to import something that is not there.
The thresholds alert; they do not cap spend.