The automated version of the Azure FinOps Multitool. Same 21 scan modules running unattended in Azure Automation on a daily schedule, delivering an HTML assessment report to your inbox every day.
- Terraform >= 1.5
- Azure CLI (logged in)
# 1. Clone and configure
git clone https://github.com/z-larsen/AzureFinOpsMultiTool-Automated.git
cd AzureFinOpsMultiTool-Automated/terraform
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars — set report_recipients to your email address
# 2. Build the runbook (assembles 24 modules into a single file)
cd ../scripts
./Build-Runbook.ps1
cd ../terraform
# 3. Deploy
terraform init
terraform apply
# 4. Authorize the email connector (one-time, ~30 seconds)
# Portal > API Connections > office365-finops-scanner > Edit API connection > Authorize
# 5. Run your first scan (or wait for the daily schedule at 6 AM UTC)
az automation runbook start \
-g rg-finops-scanner \
--automation-account-name aa-finops-scanner \
-n Run-FinOpsScan┌─────────────────────────────────────────────────────────────────┐
│ Azure Automation Account (Managed Identity) │
│ │
│ Run-FinOpsScan (PS 7.2 Runbook) │
│ ├─ 24 scan modules (costs, tags, orphans, budgets, ...) │
│ ├─ Runs daily at 6 AM UTC (customizable) │
│ └─ Authenticates via System-Assigned Managed Identity │
│ │
│ Outputs: │
│ ├─── Blob Storage ──── JSON + per-area CSVs + HTML report │
│ └─── Email ─────────── HTML report via Logic App + Office 365 │
└─────────────────────────────────────────────────────────────────┘
- Schedule fires at 6 AM UTC daily
- Managed Identity authenticates — no credentials stored
- 24 modules scan every accessible subscription: costs, tags, orphans, budgets, advisor recommendations, and more
- Results are written to blob storage (JSON + CSV + HTML)
- Logic App sends the HTML report as an email attachment
| Area | What you get |
|---|---|
| Costs | Actual MTD + forecast per subscription |
| Cost trend | 6-month monthly spend history |
| Resource costs | Per-resource spend with type, resource group, forecast |
| Tags | Every tag name/value in use, untagged resource count |
| Cost by tag | Spend broken down by CAF allocation tags |
| Orphaned resources | Unattached disks, IPs, NICs, deallocated VMs, empty ASPs, old snapshots |
| Idle VMs | Virtual machines with near-zero CPU/network utilization |
| Azure Hybrid Benefit | Windows VMs, SQL VMs, and SQL DBs missing AHB |
| Commitments | RI and Savings Plan utilization |
| Reservations & Savings Plans | Purchase recommendations with projected savings |
| Advisor | Cost-category optimization recommendations |
| Budgets | Budget vs. actual per subscription, risk levels |
| Savings realized | Monthly savings from existing RIs, SPs, and AHB |
| Policy | FinOps-related policy inventory and gap analysis |
| Anomaly alerts | Configured cost anomaly alert rules |
| Contract | EA, MCA, PAYGO, or CSP detection |
| Tenant hierarchy | Management group tree with subscription mapping |
All configuration is in terraform/terraform.tfvars. Key settings:
| Variable | Default | Description |
|---|---|---|
report_recipients |
"" |
Semicolon-separated email addresses for the daily report |
scan_scope |
"subscription" |
"subscription" or "tenant" for multi-subscription scanning |
management_group_id |
"" |
Specific management group to scan (tenant mode only) |
subscription_filter |
"" |
Comma-separated subscription IDs to restrict scanning |
scan_schedule |
"0 0 6 * * *" |
NCRONTAB expression (default: 6 AM UTC daily) |
project_name |
"finops-scanner" |
Base name for all resources |
location |
"centralus" |
Azure region |
enable_workbook |
false |
Deploy Log Analytics + Azure Workbook dashboard (advanced) |
Single subscription (default) — scans only the subscription you deploy into:
scan_scope = "subscription"Entire tenant — scans all subscriptions:
scan_scope = "tenant"Specific management group — scans subscriptions under a management group:
scan_scope = "tenant"
management_group_id = "YOUR-MG-ID"See INSTALL-GUIDE.md for the full deployment walkthrough including tenant-wide RBAC, email authorization, and troubleshooting.
Terraform creates a single resource group (rg-finops-scanner) containing:
| Resource | Purpose |
|---|---|
| Automation Account | Hosts the runbook + daily schedule |
| Storage Account | Stores scan output (JSON, CSV, HTML) |
| Runbook (PowerShell 7.2) | Orchestrates the 24-module scan |
| Daily schedule | Triggers the scan at the configured time |
| Logic App + Office 365 connector | Sends the HTML email report |
| RBAC role assignments | Reader + Cost Management Reader on the scan scope |
The Managed Identity gets read-only access:
| Role | Scope | Purpose |
|---|---|---|
| Reader | Subscription or management group | Enumerate resources |
| Cost Management Reader | Subscription or management group | Query Cost Management APIs |
| Storage Blob Data Owner | Storage account | Write scan results |
No write access to your resources. The identity can read and report, never modify.
| Component | Monthly cost |
|---|---|
| Azure Automation | Free (within 500 min/month grant) |
| Storage | < $0.01 |
| Logic App | < $0.01 (one trigger/day) |
| Total | < $1/month (often free) |
AzureFinOpsMultiTool-Automated/
├── terraform/
│ ├── main.tf # All infrastructure
│ ├── variables.tf # Input variables
│ ├── outputs.tf # Deployment outputs
│ ├── terraform.tfvars.example # Configuration template
│ └── workbook.json # Azure Workbook definition (optional)
├── function-app/
│ └── modules/ # 24 PowerShell scan modules
├── runbook/
│ └── Run-FinOpsScan.ps1 # Orchestrator script
├── scripts/
│ └── Build-Runbook.ps1 # Assembles modules into single runbook
├── INSTALL-GUIDE.md # Full deployment guide
└── README.md
Azure Automation can't import multiple script files, so Build-Runbook.ps1 concatenates all 24 modules + the orchestrator into a single Run-FinOpsScan-Assembled.ps1 that gets uploaded as the runbook. Always run Build-Runbook.ps1 before terraform apply if you've changed any module.
Run a scan anytime from the Azure portal (Automation Account > Runbooks > Run-FinOpsScan > Start) or CLI:
az automation runbook start `
-g rg-finops-scanner `
--automation-account-name aa-finops-scanner `
-n Run-FinOpsScanMonitor job status:
az automation job list `
-g rg-finops-scanner `
--automation-account-name aa-finops-scanner `
--query "[].{Status:status, Start:startTime}" -o table- Azure FinOps Multitool (Desktop) — The interactive WPF version with GUI
- FinOps Toolkit — Microsoft's official FinOps framework
- INSTALL-GUIDE.md — Full deployment walkthrough
MIT