Skip to content

Monthly Cost Reporting

Purpose

This document describes the automated monthly cloud cost reporting pipeline — what it covers, when it runs, how to read the report, and how to act on findings.


Schedule and Delivery

SettingValue
Schedule1st of each month, 12:00 UTC
DeliveryHTML email via Amazon SES
Senderops-automation (Logging account, us-west-2)
RetentionGitHub Actions artifacts, 13-month retention (enables year-over-year comparison)

The report runs automatically via GitHub Actions in the ops-automation repo. No manual trigger is required under normal operation.


Coverage

The report covers all three cloud environments in a single consolidated email.

Azure Production (ciriusgroup.com)

DataSource
Per-subscription costsAzure Cost Management REST API
Month-over-month comparisonCurrent month vs. previous month
Advisor recommendationsRight-sizing, reserved instances, shutdown candidates
Waste itemsUnattached managed disks, unattached public IPs, deallocated VMs with disk charges

Azure DDE (ciriusdde.com)

DataSource
Per-subscription costsAzure Cost Management REST API
DDE Advisor recommendationsDDE-Firewall and DDE-Billings right-sizing

AWS (7-account org)

DataSource
Org-wide costs by serviceAWS Cost Explorer API
Per-account breakdownAll 7 accounts
Waste detectionIdle EC2, unattached EBS, old snapshots, unused Elastic IPs
Anomaly detectionAWS Cost Anomaly Detection findings

Note: AWS Cost Explorer API costs approximately $0.01 per call (~$0.04/month total).


Reading the Report

Display Name Overrides

Some Azure subscription/resource group names are internal identifiers. The report applies display name overrides for clarity:

Internal NameReport Display Name
CiriusCustomersDashboard
BillingsAVD
(empty Azure service name)Prepaid/Reserved Compute

Month-over-Month Comparison

Each section shows current month spend vs. the previous calendar month. Azure uses inclusive end dates; AWS uses exclusive end dates (first of next month). This is handled automatically in the pipeline — totals are comparable.

Waste Items

Waste items are resources costing money without apparent active use:

Waste TypeWhat to Check
Unattached managed disksConfirm disk is not needed, then delete. Azure portal → Disks → filter by "Unattached"
Unattached public IPsConfirm IP is not reserved for future use, then delete
Deallocated VMsDecide: delete, resize, or leave deallocated (disk charges continue even when stopped)
Unattached EBS volumesConfirm not needed, then delete or snapshot first
Old snapshots / AMIsReview age and necessity — AMIs registered without associated instances accumulate cost

Advisor Recommendations

Azure Advisor recommendations are actionable optimization suggestions from Microsoft. Each recommendation in the report includes:

  • Resource name and subscription
  • Recommended action
  • Estimated monthly savings

Act on recommendations where the action is safe. Dismiss recommendations that are intentional configurations (e.g., an oversized VM kept large for burst capacity).


Acting on Findings

Standard Monthly Review Process

  1. Review the email when it arrives on the 1st of the month
  2. Check for anomalies — any subscription showing a large month-over-month increase warrants investigation
  3. Action waste items — use the Azure portal and AWS console to clean up identified waste
  4. Review Advisor recommendations — implement where safe, dismiss where intentional
  5. Track savings — document monthly savings from cleanup actions (reference: March 2026 cleanup identified ~$221/month AWS savings, ~$315-420/month Azure waste)

Escalation

If the report shows unexpected spend significantly above trend (e.g., >20% month-over-month spike with no known cause):

  1. Check for newly provisioned resources in the affected subscription/account
  2. Check for data transfer charges (often caused by unexpected inter-region traffic)
  3. Check AWS Cost Anomaly Detection findings for root cause clues
  4. Review GitHub Actions recent runs for any unintended resource deployments

Pipeline Architecture

GitHub Actions (cron: 1st of month)

         ├── Azure Cost Management API (prod tenant)
         ├── Azure Cost Management API (DDE tenant)
         └── AWS Cost Explorer API (management account → all 7 accounts)

              HTML email assembled

              Amazon SES → recipient email

              Results stored as
              GitHub Actions artifact
              (13-month retention)

Authentication: OIDC federated credentials across all three environments. The ops-automation OIDC trust is scoped to repo:Cirius-Group-Inc/ops-automation:ref:refs/heads/main on each environment's app registration / IAM role.

CLI and GitHub Actions role unified: The github-deploy-main IAM role is used for both CLI and GitHub Actions in the AWS environment.


Troubleshooting

SymptomLikely CauseResolution
Workflow fails to runOIDC token expired or trust mismatchCheck federated credential subject in Entra ID / AWS IAM
Azure costs showing unexpectedly lowPrevious-month date range issue (Azure inclusive vs. exclusive)Review date parameters in Azure Cost Management API call
AWS Cost Explorer returns no dataCost Explorer not enabled on management accountEnable Cost Explorer in AWS Billing console
Email not receivedSES delivery failure or identity not verifiedCheck SES send statistics in Logging account

Document History

DateChangeAuthor
March 2026Initial draft — cost report operationalRory

Internal use only — Cirius Group