Skip to main content

ops azure

On-demand queries of live Azure state — resource inventory, month-to-date costs, RBAC role assignments, and non-human identities. Every subcommand shells out to the authenticated az CLI and reflects current state; nothing is stored or cached.

Scope is the three Wasteology-managed subscriptions — dev, prod, and orbit. The Pathfinder subscriptions are deliberately out of scope. See the Cloud Governance standard for the durable policy behind these commands (ownership, intent, and process).

Never hand-maintain what Azure already knows

Resource lists, role assignments, and costs live in Azure Resource Graph and Cost Management. ops azure queries them directly rather than duplicating them into a document that goes stale the moment it is written.

Subcommands

SubcommandDescription
inventoryList all Azure resources via Resource Graph
costsMonth-to-date actual cost via Cost Management
accessRBAC role assignments (control-plane)
identitiesManaged identities + owned service principals

Subscription aliases

Every subcommand that accepts --sub uses one of these short aliases. Omitting --sub queries all three.

AliasSubscriptionID
devWasteology Development669a4356-6871-4f9b-9256-ba98d5a6eb4c
prodWasteology Productiona5a6818e-a0c0-4c6a-8b5c-21e91d75caa8
orbitWasteology-Orbit60e2b27e-fc5d-4b4b-81a9-ae650e8f2adf
Authentication

Commands run against the identity from your current az login. What you can see is bounded by your own Azure RBAC — a query is only as complete as your access.


ops azure inventory

List Azure resources across the Wasteology subscriptions via Resource Graph. Prints a table grouped by subscription and type, with a total count and a per-type breakdown. Filter by subscription (--sub) or by a resource-type substring (--type).

All resources across the three subscriptions
Terminal
$ops azure inventory
Just the Orbit subscription
Terminal
$ops azure inventory --sub orbit
Filter to resource types containing 'postgres' in the dev subscription
Terminal
$ops azure inventory --sub dev --type postgres
FlagValuesDescription
--subdev | prod | orbitLimit to one subscription (default: all three)
--typesubstringFilter to resource types containing this substring (e.g. postgres, containerapp)
--jsonEmit raw JSON instead of a table

Example table output:

                       Azure Inventory
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Subscription ┃ Resource Group ┃ Name ┃ Type ┃ Location ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ orbit │ orbit-rg-prod │ wg-pg-orbit-prod│ dbforpostgresql/… │ eastus │
└──────────────┴────────────────┴─────────────────┴────────────────────┴──────────┘

Total: 1 resource(s)
By type: dbforpostgresql/flexibleservers=1

ops azure costs

Show month-to-date actual cost per subscription via Cost Management, grouped by resource group (default) or by service. Costs are sorted descending with a per-subscription subtotal and a grand total. One failing subscription does not abort the others.

Month-to-date cost for all subscriptions, by resource group
Terminal
$ops azure costs
Production cost broken down by service
Terminal
$ops azure costs --sub prod --by service
FlagValuesDescription
--subdev | prod | orbitLimit to one subscription (default: all three)
--byresourcegroup (default) | serviceGrouping dimension
--jsonEmit raw JSON instead of tables
Requires the costmanagement extension

ops azure costs needs the costmanagement az extension. If it is missing, the command prints an actionable hint and skips the affected subscription rather than crashing:

az extension add --name costmanagement

ops azure access

List RBAC role assignments (the control-plane layer) across the Wasteology subscriptions. By default each subscription is queried at subscription scope with inherited assignments included. Pass --resource to resolve a resource by name and scope the query to just that resource, or --principal to filter to principals whose name contains a substring.

Every role assignment in the Orbit subscription
Terminal
$ops azure access --sub orbit
Assignments scoped to a single named resource
Terminal
$ops azure access --resource orbit-backend-prod
Filter to a principal and emit JSON
Terminal
$ops azure access --principal kgray --json
FlagValuesDescription
--subdev | prod | orbitLimit to one subscription (default: all three)
--resourceresource nameResolve the resource via Resource Graph and scope the query to it
--principalsubstringFilter to principals whose name contains this substring
--jsonEmit raw JSON instead of a table
Control-plane only

ops azure access reports Azure RBAC — who can manage or read the Azure resource. It does not report database data-plane access (who can connect and read rows). For that, use ops db. See Cloud Governance → Access Model for why both layers must be checked.


ops azure identities

List the non-human identities that operate Wasteology infrastructure: user-assigned managed identities (discovered via Resource Graph across all three subscriptions) and owned app-registration service principals (from az ad app list --show-mine). Service principals show their latest credential expiry, and expired credentials are flagged in red.

Managed identities + owned service principals with credential expiry
Terminal
$ops azure identities
Same data as JSON for scripting
Terminal
$ops azure identities --json
FlagValuesDescription
--jsonEmit raw JSON instead of tables
Credential expiry

The expiry shown is the latest credential end date. A service principal can authenticate as long as any one of its credentials is valid, so it is only marked EXPIRED when its newest credential is in the past. Directory (az ad) failures are warned, not fatal — you still get the managed-identity table.


📗

Cloud Governance Standard

The durable policy behind ops azure — subscription map, tracking model, access-request runbook, and rollout plan.

🗄️

ops db

Manage the data-plane layer that ops azure access does not cover — PostgreSQL users, roles, and grants.