4.4 Resource Hierarchy
Google Cloud groups everything we run in a tree: the organization at the top, folders inside it, and projects inside the folders. A project is the box that holds services, data and bills; a folder carries rules that every project inside it inherits. We use the tree to make the environments of the previous page real: one folder per environment, and in each environment the projects that host our systems.
4.4.1 The Tree¶
The tree shows project IDs and the target structure; it is not an inventory of activated services. Stage keeps its four existing project IDs. Production, Grant, the shared registry and the audit archive remain targets until separately provisioned and verified.
| Project ID or new-project pattern | Holds |
|---|---|
moonitoring-infra-seed |
The Terraform state buckets and the Terraform service accounts |
moonitoring-cicd |
Cloud Build, Cloud Deploy and the connection to the code host |
moonitoring-registry |
Container images and packages, built once and promoted by digest |
moonitoring-logging |
The organization's audit log archive |
moonitoring-<env>-net |
The environment's network, DNS zone and public edge (see Network) |
moonitoring-<env>-db |
The environment's Cloud SQL instance, with one database per system |
moonitoring-<env>-<name> |
The systems it hosts in one environment, with their services, buckets, queues and secrets: platform, farm and grant (see Where the Systems Run Today) |
moonitoring-prod-ml-lab |
Notebooks and experiments of the data scientists |
moonitoring-prod-ml |
Training pipelines and the model APIs of ai-model-platform, which other systems call |
moonitoring-sbx-<name> |
One person's sandbox |
The target is one Cloud SQL instance per environment, in its database project (moonitoring-db-stage in the existing stage), and each system has its own database on it, named after the system: access, releases, ai_gateway, farm, moochat, news, grant. These databases physically live in the database project, while the systems' services run in the application projects above. A system's service accounts must be restricted to its own database through PostgreSQL privileges; separate database names and Cloud SQL IAM alone do not establish that boundary. In prod the target instance is highly available: a standby in a second zone takes over on its own if the first zone fails. One instance per environment instead of one per database keeps the fixed cost down; a system's database moves to an instance of its own when its load or its isolation needs it.
The stage phase 1, provisioned and verified on 5 November 2026, provides five system databases and separate API/migration identities. Grant is deferred, the legacy platform database is retained, and the SQL access and isolation work remains pending.
4.4.2 Naming¶
The environment comes first in new names that carry one and in project display names (decided 2026-11-05): moonitoring-stage-farm, stage-sql, stage-vpc, stage-console.moonitoring.com. Existing resource IDs are retained. The visual alignment changes project display names; it does not recreate projects, databases, service accounts, buckets or networks. Names with no environment, such as databases and the shared projects, keep none.
| What | Pattern | Example |
|---|---|---|
| New project ID | moonitoring-<env>-<name>; existing IDs are retained |
moonitoring-prod-farm |
| Project display name | moonitoring-<env>-<name> for environment projects |
moonitoring-stage-farm |
| Environment short names | sbx, stage, prod |
moonitoring-prod-net |
| New Cloud SQL instance | <env>-sql; existing stage keeps sql-stage |
prod-sql |
| Database | The system's name, with hyphens replaced by underscores | farm, ai_gateway |
| New service account | sa-<role>, or sa-<env>-<role> for one that belongs to one environment; existing account IDs are retained |
sa-ingestion |
| Bucket | <project>-<purpose> |
moonitoring-prod-farm-raw |
| New subnet | sn-<name>; existing stage keeps stage-platform and stage-farm |
sn-farm |
| Public host | one name per system or interface under moonitoring.com, with <env>- before it outside prod |
access.moonitoring.com, stage-console.moonitoring.com |
| Group | <env>-<purpose> when it grants rights in one environment |
stage-release-admins, prod-release-admins, prod-db-access |
Shared projects listed above carry no environment: their IDs remain moonitoring-infra-seed, moonitoring-cicd, moonitoring-registry and moonitoring-logging.
A project ID is permanent and globally unique. Existing stage projects keep their IDs and resources; no project migration is required by this naming decision. The intended display names are:
| Existing project ID — used by APIs, IAM and Terraform | Project display name |
|---|---|
moonitoring-net-stage |
moonitoring-stage-net |
moonitoring-db-stage |
moonitoring-stage-db |
moonitoring-platform-stage |
moonitoring-stage-platform |
moonitoring-farm-stage |
moonitoring-stage-farm |
The display name is the editable label shown in Google Cloud. Updating it does not change the project ID or its resource addresses; the table specifies the desired labels, not a claim that the update has been applied. This convention does not rename or redefine existing legacy projects outside Terraform.
4.4.3 Rules Set on Folders¶
Rules that must hold everywhere are set as organization policies on the organization or on a folder, so no project can forget them:
- Resources only in European locations.
- No service account keys can be created.
- No default network in new projects.
- Buckets use uniform access and can never be made public.
- Cloud SQL instances never get a public IP address.
- Each folder has its own budget.