Skip to content

OCI tenancy map (live service)

The next-generation source of truth for what's in our OCI tenancies and what it costs, succeeding the static oci-resource-map.md page.

Lives in its own repo: https://git.projecteidos.com/internal/oci-tenancy-map

What it is

A small self-hosted FastAPI service that:

  • Holds read-only OCI API keys for one or more tenancies (currently ORA448Global; EIDOSDev1 pending IAM setup)
  • Continuously enumerates every resource per compartment via the OCI Resource Search API
  • Pulls last-30-day cost per compartment / service / SKU / resource via the OCI Usage API
  • Caches everything in SQLite and serves a versioned JSON REST API
  • Cross-references resources against this repo's apps/*.md so cost rolls up per business application

The docs site fetches numbers from it on page load (planned: Phase 4 below). Same container is the blueprint for per-client FinOps deployments.

Where it sits

Layer Detail
Code internal/oci-tenancy-map GitLab repo
Container python:3.12-slim, ~120 MB image, ~80 MB idle RAM
Public URL https://cost.448.global (planned)
Host O1 via Dokploy (planned)
Auth Authentik forward-auth at Caddy (planned)
Cache SQLite, single file, bind-mounted volume

Status

Phase Scope Status
1 Scaffold FastAPI + SQLite + OCI session reuse done — pushed
2 APScheduler + caching + multi-tenant config done — smoke-tested against ORA448Global; cost matches static script within £0.01
3 Dokploy deploy on O1 + Caddy + Authentik on cost.448.global pending
4 Docs JS + Parallax pilot page pending
5 Roll-out across all app pages + monitoring pending
6 Dashboard SPA (drill-down UI) future
7 Per-client deployment blueprint future

Relationship to the static script

The static script at infra/scripts/oci-resource-map.py is now the offline fallback — useful for ad-hoc CLI runs and as a recovery tool if the container is down. The container is the live source of truth.

Both share the same categorisation + system-vs-user heuristics (the container imports them from its own app/categorise.py, mirroring the script's logic to keep them consistent).

Why we built it instead of adopting an existing tool

Reviewed in May 2026: Komiser is effectively dormant (last real commit Jan 2025), Steampipe's OCI plugin has 166 tables but zero cost tables, CloudQuery has no OCI plugin at all, InfraCost is estimates not actuals, OpenCost is K8s-only. No OSS tool exposes the OCI Usage API for cost actuals as queryable JSON. Combined with the principle "every adopted dependency is another maintenance + abandonment risk," rolling our own was the right call. See the new repo's ARCHITECTURE.md for the full reasoning.

Ad-hoc cost queries

ADB daily cost report

To get a per-day breakdown of paid ADB (Autonomous Database / APEX / Exadata) costs for the last 30 days across both tenancies:

cd /home/coder/oci-tenancy-map
.venv/bin/python3 ../engineering/infra/scripts/adb-daily-cost.py

Options:

Flag Default Example
--days N 30 --days 7
--profile NAME all tenancies --profile EIDOSDev1

The script uses the OCI Usage API with DAILY granularity and filters to ADB-related SKUs (Autonomous, APEX Application Development, Exadata Storage). Output is a detail table followed by a per-day total and a 30-day sum.

The same .venv is used by the live oci-tenancy-map service — no separate install needed. Both OCI profiles (ORA448Global, EIDOSDev1) are hardcoded in the script alongside their tenancy OCIDs; update them if profiles are renamed.

Operating it

See the new repo's deploy/RUNBOOK.md: adding a tenancy, rotating API keys, forcing a refresh, inspecting freshness, common failure modes.