Goal: a project layout where a mistake in dev cannot touch prod.

Structure:
- Organization -> folders (prod, non-prod) -> projects per environment per workload (app-prod, app-staging, app-dev).
- One billing account linked to all projects; use budgets per project for cost visibility.
- Shared VPC host project for networking if teams share VPCs; service projects attach to it.

Why project-per-environment:
- IAM blast radius: a staging SA with broad roles cannot reach prod data if prod is a different project with no grants.
- Quotas are per project: a runaway in dev does not eat prod quota.
- Billing attribution is clean per project.
- Deleting a project is the ultimate cleanup; you cannot delete half a project by accident the way you can delete half a folder of resources.

Setup order:
1. Create folders under the org.
2. Create projects in the right folders (project creation needs resourcemanager.projects.create at the folder/org).
3. Link the billing account to each project.
4. Enable the APIs each project needs (per-project enablement).
5. Apply org policies at the folder level (prod stricter than dev).

Traps:
- Creating all projects at org root: you lose folder-level policy and IAM grouping. Put them in folders from day one; moving later is possible but annoying.
- API enablement is per project: enabling BigQuery in dev does not enable it in prod. Terraform per project or a bootstrap script.
- Default networks and default service accounts exist per project; harden or remove per project, not once.
- Billing account permissions: the person linking billing needs billing.resourceAssociations.create, separate from project creation rights.

Verify: list projects per folder, confirm billing linked on each, and confirm a dev identity has zero IAM on prod projects.