We are currently looking at doing a migration from Logic Apps ISE to Logic Apps Standard and Logic App Consumption. We have approx 500 logic apps. A few things I need to understand about my Logic Apps are:
- Which ones are being used and which arent
- Are any of them having errors
- Roughly how complex are the logic apps
- How much much would the Logic App have cost if id ran it on consumption
I have put together a Powershell script which can be ran and it will query my Logic Apps and then get a bunch of the metric counters for them and then I can use this to see how many times it ran, how many failures, I can use the number of actions to get an idea of how complex it might be and the triggers and actions to calculate an approximate cost for the Logic App if it were consumption.
I am then running this script in a devops pipeline so I can get the report on a regular basis so I can easily spot logic apps that have had errors each day and also use the info to help me make decisions about if a Logic App will be migrated to standard or consumption.
It was pretty interesting seeing the old 80/20 rule come into play where around 20% of our Logic Apps would spend approx 80% of the money if they were all on consumption.
Anyway im sure the script will be handy for others to use and modify so its below.
param (
[string]$resourceGroup = "Mikes-RG",
[string]$subscriptionId = 'Mikes-SubscriptionID',
[String]$folderPath = "c:\Temp\",
[String]$fileName = "LogicAppOverview-30day",
[int]$daysToGoBack = -30
)
#Prices in CAD for a run of a logic app action
$logicAppActionCost = 0.000034
$resourceGroupToLower = $resourceGroup.ToLower()
$startDate = (Get-Date).AddDays($daysToGoBack).Date
$logicAppsQuery = "resources
| where type == 'microsoft.logic/workflows'
| where resourceGroup == '$resourceGroupToLower'
| where subscriptionId == '$SubscriptionId'"
$logicAppOverviewList = New-Object "System.Collections.Generic.List[System.Object]"
Write-Host $logicAppsQuery
$logicAppsQueryResponse = Search-AzGraph $logicAppsQuery -First 1000
Write-Host $logicAppsQueryResponse.Count " logic apps found"
foreach($item in $logicAppsQueryResponse){
Write-Host $item.Name
Write-Host $item.ResourceId
$runTotal = 0
$billableActionsTotal = 0
$billableTriggersTotal = 0
$totalBillableItems = 0
$totalBillableCost = 0
$totalActionsSkipped = 0
$totalActionsFailed = 0
$totalRunsFailed = 0
#Runs
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "RunsStarted" -AggregationType Total -DetailedOutput
foreach($data in $metricResults.Data){
$runTotal = $runTotal + $data.Total
}
#Actions (ActionsStarted)
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "ActionsStarted" -AggregationType Total
foreach($data in $metricResults.Data){
$billableActionsTotal = $billableActionsTotal + $data.Total
}
#Actions Skipped (ActionsSkipped)
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "ActionsSkipped" -AggregationType Total
foreach($data in $metricResults.Data){
$totalActionsSkipped = $totalActionsSkipped + $data.Total
}
#Actions Failed (ActionsFailed)
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "ActionsFailed" -AggregationType Total
foreach($data in $metricResults.Data){
$totalActionsFailed = $totalActionsFailed + $data.Total
}
#Runs Failed (RunsFailed)
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "RunsFailed" -AggregationType Total
foreach($data in $metricResults.Data){
$totalRunsFailed = $totalRunsFailed + $data.Total
}
#Triggers (TriggersStarted)
$metricResults = Get-AzMetric -ResourceId $item.ResourceId -TimeGrain 1.00:00:00 -StartTime $startDate -MetricName "TriggersStarted" -AggregationType Total
foreach($data in $metricResults.Data){
$billableTriggersTotal = $billableTriggersTotal + $data.Total
}
Write-Host $item.Name " has: "
Write-Host $runTotal " runs"
Write-Host $billableActionsTotal " billable actions"
Write-Host $billableTriggersTotal " billable triggers"
Write-Host $totalActionsFailed " actions failed"
Write-Host $totalActionsSkipped " actions skipped"
Write-Host $totalRunsFailed " runs failed"
$totalBillableItems = $billableActionsTotal + $billableTriggersTotal
$totalBillableCost = $totalBillableItems * $logicAppActionCost
Write-Host $totalBillableItems " total billable items"
Write-Host "$" $totalBillableCost "CAD approx consumption cost"
$complexityPoints = "Unknown"
if($runTotal -gt 0){
$actionsForComplexity = $billableActionsTotal + $totalActionsSkipped
$complexityPoints = $actionsForComplexity / $runTotal
}
$logicAppOverview = New-Object -TypeName psobject
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'Name' -Value $item.Name
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'Runs' -Value $runTotal
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'BillableActions' -Value $billableActionsTotal
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'BillableTriggers' -Value $billableTriggersTotal
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'TotalBillableItems' -Value $totalBillableItems
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'ActionsFailed' -Value $totalActionsFailed
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'ActionsSkipped' -Value $totalActionsSkipped
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'RunsFailed' -Value $totalRunsFailed
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'ApproxConsumptionCostCAD' -Value $totalBillableCost
$logicAppOverview | Add-Member -MemberType NoteProperty -Name 'ComplexityPoints' -Value $complexityPoints
$logicAppOverviewList.Add($logicAppOverview)
}
$filePath = $folderPath + + $fileName + "-" + $resourceGroup + ".csv"
$logicAppOverviewList | Export-Csv -Path $filePath -NoTypeInformation