microsoft / microsoft/finops-toolkit
Automatically download Microsoft invoice PDFs into the hub data lake
Nobody has claimed this yet.
- Dominant language
- PowerShell
- Stars
- 603
- Forks
- 248
- Avg merge
- 7d 11h
- Merged PRs (30d)
- 11
Description
🔦 Context
FinOps hubs give us excellent cost and usage data through Cost Management exports, but the invoice documents themselves are not part of the data lake. Today, teams that need the actual invoice PDFs — for month-end close, audit evidence, internal chargeback packages, or reconciliation against the FOCUS dataset — download them manually from the Azure portal, one billing profile at a time.
For organizations with several billing profiles, this is a recurring monthly chore that is easy to forget and hard to audit. It also means the invoice and the cost data that explains it live in two different places.
💡 Proposal
Add an optional hub app that downloads Microsoft invoice PDFs from the Billing API into the existing ingestion container on a monthly schedule.
Proposed shape:
- New app under a
Microsoft.Billing/Invoicesnamespace, following the existing hub app pattern (app.bicep+metadata.bicep, registered throughfx/hub-app.bicep) - Opt-in via a new step in the deployment wizard, disabled by default — existing hubs see no change unless they explicitly enable it
- Billing accounts configured in
settings.json; when left blank, derived from the billing account scopes the hub already monitors - Configurable day of month for the schedule (invoices are generally available within the first few days of the month)
- Files land in a predictable hierarchy for downstream reporting:
ingestion/
└── invoices/
└── {YYYY-MM}/
└── {billingProfileId}/
└── {purchaseOrderNumber|no-po}/
└── {invoiceNumber}.pdf
No new Azure resources are created — the app only adds artifacts to the Data Factory the hub already deploys. Estimated cost is roughly US$1/month in activity runs for a few dozen invoices.
🧩 Known constraints
- MCA/MPA only. The
Microsoft.Billinginvoice APIs don't cover legacy Enterprise Agreement. The pipeline should degrade gracefully (empty list, no failure) rather than error out. - Billing Reader can't be granted by the template. The role assignment scope is
/providers/Microsoft.Billing/billingAccounts/{id}, which is tenant-level and outside any subscription, so a resource-group–scoped deployment can't create it. This needs to be a documented post-deployment step, ideally backed by a helper cmdlet. - Download URLs are short-lived SAS links (roughly one hour), so the download loop needs bounded parallelism.
- The activity that requests the download URL must use
secureOutputsince the response body contains a SAS token.
🌱 Possible follow-ups (out of scope for the initial change)
- A Power BI page reconciling invoices against FOCUS cost data by
invoiceId - Ingesting invoice
Transactions(line items) via the API alongside the PDFs - A control table tracking which invoices have already been downloaded
🙋 Offer to contribute
I have a working implementation of this and would be happy to open a PR if the team is interested in the direction. Happy to adjust the namespace, wizard placement, or configuration surface based on your preferences before I do — I'd rather align early than send a large PR that needs reshaping.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing existing hub apps and the registration path in app.bicep, metadata.bicep, and fx/hub-app.bicep, then inspect settings.json and the deployment wizard for configuration conventions. Confirm how the existing ingestion container and Data Factory artifacts are modeled. Done means an optional Microsoft.Billing/Invoices app can download invoices into the proposed hierarchy while handling the stated API and permission constraints.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, powershell
- Domain
- cloud, data-engineering, devops
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100