Inventory Schema — inventory.yaml¶
Classification: CONFIDENTIAL — Internal Use Only Document:
governance/inventory-schema.md· v1.2 · 2026-06-26 · GPUS-IT
1. Purpose¶
inventory.yaml at the repository root is the single source of truth for every
host, hypervisor, network appliance, storage device, power device, and
managed cloud service referenced anywhere in the GPUS-IT infrastructure
documentation and portals.
This page documents its schema, allowed field values, and the build-time transformations that derive consumer artifacts from it.
2. Top-level structure¶
version: 1
last_updated: "YYYY-MM-DD"
inventory:
linux_hosts: { <ID>: { … } }
hypervisors: { <id>: { … } }
power_devices: { <id>: { … } }
network_devices: { <id>: { … } }
storage: { <id>: { … } }
cloud_services: { <id>: { … } }
compute_instances: { <id>: { … } }
external_references: { <id>: { … } }
cleanup_notes: { <id>: { … } }
The top-level inventory: key holds the seven managed-infrastructure
categories. The sibling external_references: key is a separate
allow-list for cross-reference targets that exist as concepts but are not
managed as first-class inventory entities (e.g. workstations, PSU partial
references, unidentified rogue assets). The sibling cleanup_notes: key
records orphaned / dead resources queued for deletion — not managed
assets (the coverage check ignores it); see §11.
3. ID conventions¶
| Category | ID case | Examples |
|---|---|---|
linux_hosts |
UPPERCASE | SKY, RAIN, OAK |
hypervisors |
lowercase | water, fire, flower |
power_devices |
lowercase, snake_case for compounds | pickle, fennel, power_strip_1 |
network_devices |
snake_case | wdc_fw_primary, wdc_stack_0, gl5_firewall |
storage |
snake_case | nas, visuals_storage_exp_1, ocean |
cloud_services |
snake_case | gpus_forms_db |
external_references |
snake_case | stone, kvm_switch, fire_psu_1 |
The Linux-host UPPERCASE convention is preserved because servers.py (a
generated artifact, see §6) keys on those names and several front-end
literals already use them.
4. Required fields per entity¶
Universal (all entities in the five inventory categories)¶
| Field | Type | Required | Notes |
|---|---|---|---|
desc or role |
string | one of these | Short human description. |
location |
enum | yes | wdc, gcp, mdec, dc_apartments, oakec |
monitoring_status |
enum | yes | See §5 |
monitoring_intent |
enum | yes | See §5 |
documented_in |
list[path] | yes | Doc paths referencing this entity. Each path ends in .md or .csv — see §8. |
Category-specific¶
| Category | Additional required fields |
|---|---|
linux_hosts |
ip, fqdn, user, services, tags, prom_ip |
hypervisors |
fqdn, ip, hypervisor, vms |
power_devices |
type (one of ups | ups_extension | pdu | power_strip_unmanaged), powers |
network_devices |
type (one of firewall | switch | wireless_ap), model |
storage |
type (one of nas | storage | storage_controller | vm) |
cloud_services |
type (e.g. cloud_sql, cloud_run, pub_sub, cloud_storage_bucket, cloud_scheduler, host_resident_service) |
compute_instances |
project, platform, network_domain, role, disposition (see §11) |
host_resident_service— a long-running service that lives on a managed Linux host rather than as a standalone GCP-managed resource (e.g. a systemd unit on MAPLE). Link it to its host withhosted_on: <HOST_ID>. It is acloud_servicesentry, not alinux_hostsentry, soregenerate-servers-py.pynever emits it intoservers.pyand the SSH fan-out backends do not try to reach it as a host.
Optional but common¶
ip, mac, serial, mgmt_port, dashlane, email_alerts, hardware_model,
hypervisor, powers, powered_by, fed_from, hosted_on, vms,
criticality, eol_note, risk, note, justification, decommissioned_reason,
action_required.
Relaxations by status¶
Entities with monitoring_status: unmonitored or decommissioned skip
some required fields that don't apply:
unmonitoredskipsmodel,ip,fqdn(unmanaged devices often have none).decommissionedskipsvms,powers,ip,fqdn,hypervisor,model.
The coverage check enforces these relaxations automatically.
5. Enum values¶
monitoring_status¶
| Value | Meaning |
|---|---|
live |
Telemetry actively wired and reporting today. |
planned |
Exists or committed to exist; telemetry not yet wired. UI renders striped-yellow status dot. |
unmonitored |
Exists, no telemetry intent. Requires justification. UI renders grey status dot. |
decommissioned |
No longer in service. Requires decommissioned_reason. UI renders strike-through, not interactive. |
monitoring_intent¶
| Value | Applies to |
|---|---|
ssh+prometheus |
Linux hosts |
vmware_exporter+syslog |
ESXi hypervisors |
snmpv3 |
APC PDU / UPS (default) |
snmpv2c |
Legacy APC PDUs (Fennel exception) |
snmp+dsm_syslog |
Synology NAS / storage |
meraki_api+syslog |
Meraki firewalls / switches / APs |
snmpv3+syslog |
Non-Meraki firewalls (GL5) |
cloud_sql_metrics+iam_audit_log |
Managed Cloud SQL instances |
pubsub_dlq_alerting |
Pub/Sub pipelines whose failure detection is dead-letter depth + worker DLQ-drain Slack alerting (α ClamAV scan + 2.5(c) routing) |
none |
Unmonitored entities (requires justification) |
criticality¶
Optional but recommended for new entries from 2026-05-14 forward.
The coverage check rejects values outside this set. Existing
pre-2026-05-14 entities are being backfilled — see
mkdocs-portal/CLAUDE.md known-issues for owner/progress.
| Value | Meaning | Example entities |
|---|---|---|
critical |
Outage causes immediate revenue loss, production data loss, or org-wide work stoppage. | Production Cloud SQL, primary firewalls, hypervisors hosting active workloads. |
high |
Outage degrades a major function or breaks a single site's connectivity. | Site firewalls, core switches, primary NAS. |
medium |
Outage affects a localized function or single team. | Access switches, site APs in shared workspaces. |
low |
Outage affects individual convenience or non-essential coverage. | Residential APs, conference-room AV. |
6. Generated artifacts¶
| Artifact | Generated from | Generator | When |
|---|---|---|---|
servers.py (repo root) |
inventory.linux_hosts |
scripts/regenerate-servers-py.py |
Pre-commit (human) |
status-backend/servers.py |
inventory.linux_hosts |
scripts/regenerate-servers-py.py |
Pre-commit (human) |
soc-backend/servers.py |
inventory.linux_hosts |
scripts/regenerate-servers-py.py |
Pre-commit (human) |
status-site/inventory.json |
inventory.yaml |
Cloud Build step | Per deploy |
soc-site/inventory.json |
inventory.yaml |
Cloud Build step | Per deploy |
The three servers.py files remain committed for local development. The
two inventory.json files are baked into the site Docker images at build
time and not committed.
regenerate-servers-py.py branches on monitoring method (§11):
ssh-pollhosts (the legacylinux_hostsfleet) populateWDC_SERVERS/CLOUD_SERVERSand the combinedSERVERSdict — the SSH fan-out path, unchanged.- Any other method (
wazuh-agent,node-exporter,none, …) — including everycompute_instancesentry — is rendered into a separateDOCUMENTED_HOSTSdict that is excluded fromSERVERS. The backends must never SSH a host without an ssh-poll path. Each documented host carries a neutralmonitoring_statelabel, never a passing state.
7. Optional fields¶
risk (free text)¶
Documents known risk associated with the entity. Read by humans only; coverage script does not act on it. Example: SPOF callouts, missing credentials, legacy model warnings.
justification (free text)¶
Required when monitoring_status: unmonitored. Documents why monitoring
is deferred. Coverage check fails if missing on an unmonitored entity.
decommissioned_reason (free text)¶
Required when monitoring_status: decommissioned. Documents what
removed the entity from service. Coverage check fails if missing on a
decommissioned entity.
8. documented_in — accepts .md and .csv¶
The documented_in: field is a list of relative paths pointing at
documentation pages or host-registry CSVs that reference the entity.
.mdpaths: the coverage check verifies the file exists and contains the entity ID as a case-insensitive substring of its content..csvpaths: the coverage check verifies the file exists and that some column value in some row contains the entity ID (case-insensitive). CSV rows are treated as legitimate documentation — hostregistries are part of the docs portal nav and are authoritative for hostname/MAC/serial data.
A page-existence-but-not-mentioned warning is informational unless
escalated via .coverage-exceptions.yaml.
9. Referential integrity¶
powers:, powered_by:, fed_from:, hosted_on:, and vms: reference
IDs from other entities. The coverage check (§10) verifies every reference
resolves to either an inventory entity OR an external_references entry.
10. Coverage check¶
The script at scripts/check-component-coverage.py (see
component-coverage-standard.md)
enforces:
- Every entity has all required fields (with status-based relaxations).
- Every
monitoring_status: unmonitoredhasjustification. - Every
monitoring_status: decommissionedhasdecommissioned_reason. - Every entity has
documented_inwith at least one path that exists. - Every doc path in
documented_inmentions the entity ID (case-insensitive content match for.md, column-value match for.csv). - Every reference in
powers:/powered_by:/fed_from:/hosted_on:/vms:resolves to a known ID. - The committed
servers.pyfiles match what would be generated frominventory.linux_hosts. - Identifiers cited in
docs/hostregistry/*.csvappear in the inventory (excluding workstations, desktops, printers, and other non-WDC scope).
Drift fails the build unless covered by an active exception in
.coverage-exceptions.yaml.
11. compute_instances and the cross-project asset fields¶
The compute_instances category holds GCE VM instances that span projects
and platforms — most notably the gpus-it-infrastructure data-team fleet
documented at
infrastructure/gpus-it-infrastructure.md.
It is distinct from linux_hosts (the SSH-poll + node_exporter fleet the
gpus-infra backends fan out to): compute_instances entries are
documented-but-not-polled.
New schema fields¶
These fields are optional on the existing categories (added to the
linux_hosts fleet as project: gpus-infra / platform: linux) and
required on compute_instances where noted.
| Field | Type | Required on compute_instances |
Notes |
|---|---|---|---|
project |
enum | yes | gpus-infra | gpus-it-infrastructure |
platform |
enum | yes | linux | windows | gke |
network_domain |
enum | yes | wdc | gpus-infra | gl5-shared |
role |
string | yes | Human description (satisfies the desc-or-role rule). |
disposition |
string | yes | Lifecycle intent: keep, migrate (…), rebuild (…), decommission (…), investigate. |
role_status |
string | no | confirmed-data-team | unconfirmed. |
os / os_eol |
string | no | OS identifier and end-of-life date. Write explicit null for os_eol when unknown. |
ip_public |
string | null | no | External IP. Write an explicit null when the instance has none. |
zone, machine_type, state |
string | no | GCE placement / size / power state (running | terminated). |
The monitoring: block¶
compute_instances use a nested monitoring block instead of the flat
monitoring_status / monitoring_intent fields:
monitoring:
method: wazuh-agent # ssh-poll | wazuh-agent | node-exporter | none
collector: wdc # where telemetry lands (e.g. WDC Wazuh / Prometheus)
status: pending-path # see enum below
monitoring.status enum (superset of the flat monitoring_status enum):
| Value | Meaning |
|---|---|
live |
Telemetry actively reporting. |
planned |
Committed; not yet wired. |
pending-path |
Collector path defined (agent/exporter intended) but not yet reporting. Rendered "● monitoring pending". Counts as portal-present, but still requires an IAR entry. |
not-monitored |
No telemetry intent (e.g. terminated / unknown instance). |
decommissioned |
No longer in service. |
The coverage check accepts either the flat fields or the nested
block — the block satisfies the universal monitoring_status /
monitoring_intent requirements. The generator's ssh-poll-vs-other
branch (§6) keys off monitoring.method (legacy hosts with
monitoring_intent: ssh+prometheus resolve to the ssh-poll method).
Coverage rules specific to compute_instances¶
In addition to the universal rules (§10):
- Portal presence — every non-
decommissionedcompute_instancesentry (and any asset taggedproject: gpus-it-infrastructure) must appear in bothstatus-siteandsoc-siterender sources, as a literaldata-svc-idcard or via thecompute-instances-rendersentinel.pending-path/not-monitoredstill require the card. - IAR entry — every
gpus-it-infrastructureasset must be registered incompliance/iar.md(CIS Control 1), even when monitoring is pending.
12. cleanup_notes¶
A top-level sibling of inventory: recording orphaned / dead resources
queued for deletion (e.g. unattached disks, dead GKE PVCs). These are
not managed assets — no monitoring intent, no portal card, no
servers.py entry — and the coverage check ignores this key entirely.
Promote an entry to a first-class category only if the resource re-enters
service.