Logic Apps Consumption is easy to start with, which is exactly why subscriptions fill up with workflows nobody owns: proofs of concept, test copies and integrations of systems that were retired years ago. Two disciplines bring that back under control: consistent diagnostics on every workflow, and a safe, repeatable way to find and remove what is idle or always failing. This guide covers both.
Why this matters: cost and blind spots
An unused Consumption workflow is not automatically free. Workflows with polling triggers keep generating billable trigger executions every time the trigger checks for events, even when nothing is found and no run starts. And a workflow without diagnostics is a blind spot: when it fails, nobody notices until a business user does.
Part 1: diagnostics on every workflow
What to collect
For Consumption logic apps, add a diagnostic setting with the log category Workflow runtime diagnostic events (WorkflowRuntime) and AllMetrics, and send it to a Log Analytics workspace. Optionally archive to a storage account or stream to an event hub for a SIEM. Installing the Logic Apps Management solution in the workspace gives you a ready-made summary of run status per workflow.
For a single workflow from the command line:
az monitor diagnostic-settings create \
--name diag-to-law \
--resource /subscriptions/<sub-id>/resourceGroups/rg-integration/providers/Microsoft.Logic/workflows/la-order-sync \
--workspace /subscriptions/<sub-id>/resourceGroups/rg-monitoring/providers/Microsoft.OperationalInsights/workspaces/law-integration \
--logs '[{"category":"WorkflowRuntime","enabled":true}]' \
--metrics '[{"category":"AllMetrics","enabled":true}]'Doing it at scale
Configuring diagnostics workflow by workflow does not survive the next new workflow. Use Azure Policy instead: Azure provides built-in “Enable logging by category group” policies for many resource types, including microsoft.logic/workflows, that deploy a diagnostic setting to Log Analytics when it is missing. Assign the policy at management group or subscription level and run a remediation task for existing workflows. New workflows then get diagnostics without anyone remembering it.
Two details to keep in mind:
- Resource logs use a store-and-forward architecture with built-in redundancy and retries, but without transactional guarantees. They are excellent for monitoring and trends, not for financial reconciliation.
- Use tracked properties and a client tracking ID to correlate runs with business keys, so you can search for an order number instead of a run ID.
Queries that pay off immediately
Failed runs per workflow over the last day:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.LOGIC"
| where Category == "WorkflowRuntime"
| where OperationName == "Microsoft.Logic/workflows/workflowRunCompleted"
| where TimeGenerated > ago(1d)
| summarize Failed = countif(status_s == "Failed"), Total = count() by resource_workflowName_s
| where Failed > 0
| order by Failed descWorkflows that ran but never succeeded in the last 30 days – your cleanup candidates:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.LOGIC"
| where OperationName == "Microsoft.Logic/workflows/workflowRunCompleted"
| where TimeGenerated > ago(30d)
| summarize Succeeded = countif(status_s == "Succeeded"), Runs = count() by resource_workflowName_s
| where Succeeded == 0Turn the first query into an alert rule with an action group that reaches the owning team, not a shared mailbox nobody reads.
Part 2: finding idle and always-failing workflows
Two categories deserve attention:
- Idle – no runs within a chosen window, including workflows that never ran at all.
- Always failing – ran within the window but not a single run succeeded.
Microsoft’s Tech Community has published an open-source PowerShell script (LA-CleanUp, Invoke-LogicAppCleanup.ps1) that reports both categories for a subscription, with parameters such as -IdleDays (default 90), -FailureWindowDays, -ResourceGroup, -SkipIdle and -SkipAlwaysFailing. Whether you use that script or the KQL above, the output is a candidate list – not a delete list.
A safe cleanup procedure
- Report the candidates with resource group, last run time and last status.
- Find the owner. Use tags such as owner and cost center; workflows without tags go to the subscription owner. Make missing tags a policy finding from now on.
- Confirm with the owner that the workflow is not seasonal – a year-end or quarterly process can look idle for 89 days.
- Disable first. A disabled workflow stops its trigger, so polling stops costing money, and you can enable it again within seconds if someone complains.
- Observe for an agreed period, for example one full business cycle.
- Export the definition to source control before deletion, so the logic is not lost.
- Delete the workflow and any API connections only it used.
Prevent the next pile
- Require owner and environment tags on
Microsoft.Logic/workflowsthrough Azure Policy. - Keep diagnostics mandatory through the policy assignment described above.
- Give proofs of concept an expiry date tag and review it monthly.
- Deploy production workflows only from pipelines, so every production workflow has a repository and an owner.
If a group of Consumption workflows turns out to be business-critical and frequently changed, consider moving it to Logic Apps Standard, where several workflows share one app, deployment is code-based and networking options are richer – see Logic Apps Standard connections in production and routing Logic Apps service health alerts to owners.





0 Comments