billing_export — version 1.0

Source: presets/billing-export.satz

Purpose

Cloud Billing usage and cost data, exported to BigQuery in a project of its own — where the spend is KEPT, as opposed to the budget that alarms on it.

A budget (presets/organization-budget.satz) says when a threshold is crossed; this says what the money went on, per project, per SKU, per day, queryable months later.

ITS OWN PROJECT. The export is not infrastructure and its dataset is read by whoever reviews spend, so it lives in a project of its own rather than in the infrastructure project: reading the billing dataset then never means reading the state bucket beside it. The project takes the same billing account as the infrastructure project and carries one API, BigQuery's.

SWITCHING THE EXPORT ON IS A CONSOLE STEP. Cloud Billing has no API, no gcloud command and no Terraform resource for pointing a billing account at a dataset. This pack builds everything the console asks for — the project, the dataset, and the export account's access to it — and the notice below names the step and the param that acknowledges it. Until it is done the dataset stays empty.

THE EXPORT ACCOUNT. Google writes the export as billing-export-bigquery@system.gserviceaccount.com, a Google-owned account in a Google-owned domain, the same for every customer. Two things follow, and this pack does both: it holds roles/bigquery.dataEditor on the dataset, and — because it lives outside the customer's organisation — it is CONTRIBUTED to the CIS baseline's allowed_policy_member_subjects, so domain-restricted sharing lets the grant through. Switch this pack off and the entry goes with it.

NO CLAIM. No catalog control covers billing export, so this pack witnesses nothing.

Use it

params {
  use_billing_export = true

  // the pack's own defaults — copy only the lines you change
  billing_export_project_id = "{customer_shortname}-billing-001"
  billing_export_project_folder = ""
  billing_export_project_display_name = billing_export_project_id
  billing_export_dataset_id = "{customer_shortname}_billing_export"
  billing_export_location = default_region
  billing_export_description = "Cloud Billing usage and cost data, exported continuously"
}

use "presets/billing-export.satz" when use_billing_export

use_billing_export is the gate: while it is falsy the pack contributes nothing — no resources, no params, no claims. It is declared by estate_map, and the estate's own binding wins.

Needs from outside the pack:

Params

param default
billing_export_project_id "{customer_shortname}-billing-001"
billing_export_project_folder ""
billing_export_project_display_name billing_export_project_id
billing_export_dataset_id "{customer_shortname}_billing_export"
billing_export_location default_region
billing_export_description "Cloud Billing usage and cost data, exported continuously"

Questions

What to ask before this pack is configured, and what changing the answer costs.

asks about prompt reversal blast recommends
billing_export_project_id The project that holds the billing export recreate high —
billing_export_project_folder The folder the billing-export project is created in — a folder the estate declares as google_folder.<label>.name, an existing one by its numeric id, or empty for the organisation edit low —
billing_export_dataset_id The dataset the billing export writes into recreate high —
billing_export_location Where the billing dataset lives (a BigQuery location, e.g. europe-west3 or EU) recreate high —

billing_export_project_id — A project id is immutable. Changing it later creates a second project and abandons the first, with the billing history inside it — and the console export has to be pointed at the new dataset by hand.

billing_export_project_folder — It is the only thing that decides where the project lands. Left empty, the project is created directly under the organisation and inherits the organisation's policies and IAM alone. Changing it afterwards moves a live project between parents, which changes the policies and the grants it inherits.

billing_export_dataset_id — Whoever can read it reads what every project in the organisation costs. A dataset id cannot be renamed: a new one is a new dataset the console export has to be pointed at, and the history stays in the old one.

billing_export_location — A dataset's location cannot change: moving it means a new dataset and no history. Where the CIS pack enforces allowed resource locations, a location outside that list is refused. The default follows the estate's own default region.

Notices

What to run once this pack is switched on. satz shows each notice when the pack goes on and until the estate binds its param true; every command that writes to the organisation refuses while one whose severity is error is open.

param run severity what and why
billing_export_enabled https://console.cloud.google.com/billing — the billing account, Billing export, BigQuery export, Edit settings warning Cloud Billing has no API, no gcloud command and no Terraform resource for switching the export on. Apply this pack first, then in the Cloud console open Billing, pick the billing account, go to Billing export, BigQuery export, and point Standard usage cost at the project billing_export_project_id names and the dataset billing_export_dataset_id names. The dataset stays empty until that is done. Bind this param true once it is.

Contributes

To allowed_policy_member_subjects, while this pack is on:

resource type labels
google_bigquery_dataset billing_export
google_bigquery_dataset_iam_member billing_export_writer
google_project billing_export_project

Claims

None — this pack proves no control by itself.

History

version date change
1.0 2026-09-22 Cloud Billing usage and cost data exported to BigQuery: a project of its own, the BigQuery API on it, the dataset, and Google's export account's dataEditor on it — with that account contributed to allowed_policy_member_subjects, and a notice for the console step Cloud Billing has no API for

The whole library's history: the changelog in presets/CHANGELOG.md.

Notes

No notes yet.