Last active
October 29, 2021 08:12
-
-
Save mattbrailsford/84d23e03cd18c7b657e1ce755a36483d to your computer and use it in GitHub Desktop.
Azure SignalR Service AutoScale Powershell Azure Function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"bindings": [ | |
{ | |
"name": "Timer", | |
"type": "timerTrigger", | |
"direction": "in", | |
"schedule": "0 */5 * * * *" | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"IsEncrypted": false, | |
"Values": { | |
"AzureWebJobsStorage": "UseDevelopmentStorage=true", | |
"FUNCTIONS_WORKER_RUNTIME": "powershell", | |
"ServicePrincipalClientId": "{YOUR_SERVICE_PRINCIPAL_CLIENT_ID}", | |
"ServicePrincipalKey": "{YOUR_SERVICE_PRINCIPAL_KEY}", | |
"ServicePrincipalTenantId": "{YOUR_SERVICE_PRINCIPAL_TENANT_ID}", | |
"SignalRResourceId": "{YOUR_SIGNALR_SERVICE_RESOURCE_ID}" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Input bindings | |
param($Timer) | |
# Variable definitions | |
$resourceId = $env:SignalRResourceId | |
$connectionsPerUnit = 1000 # Number of concurent connections you can have per unit | |
$unitCounts = 1,2,5,10,20,50,100 # Supported SignalR Unit Counts | |
$scaleThreshold = .95 # Percentage threshold at which to scale | |
# Authenticate the service principle | |
$clientId = $env:ServicePrincipalClientId | |
$key = $env:ServicePrincipalKey | |
$securePassword = ConvertTo-SecureString $key -AsPlainText -Force | |
$credentials = New-Object System.Management.Automation.PSCredential($clientId, $securePassword) | |
$tenantId = $env:ServicePrincipalTenantId | |
Connect-AzAccount -ServicePrincipal -Credential $credentials -Tenant $tenantId | |
# Get information about the current resource state | |
$signalRResource = Get-AzResource -ResourceId $resourceId -Verbose | |
$currentUnitCount = [int]$signalRResource.Sku.Capacity | |
# Only scale if we are on the Standard_S1 plan | |
if ($signalRResource.Sku.Name -eq "Standard_S1") { | |
# Get metrics for the last 5 minutes | |
$connectionCountMetric = Get-AzMetric -ResourceId $resourceId -MetricName "ConnectionCount" -TimeGrain 00:05:00 -StartTime (Get-Date).AddMinutes(-5) -AggregationType Maximum | |
$maxConnectionCount = $connectionCountMetric.Timeseries.Data[0].Maximum | |
# Calculate the target unit count | |
$targetUnitCount = 1 | |
foreach ($unitCount in $unitCounts) { | |
$unitCountConnections = $unitCount * $connectionsPerUnit | |
$unitCountConnectionsThreshold = $unitCountConnections * $scaleThreshold | |
if ($unitCountConnectionsThreshold -gt $maxConnectionCount -or $unitCount -eq $unitCounts[$unitCounts.Count - 1]) { | |
$targetUnitCount = $unitCount | |
Break | |
} | |
} | |
# See if we need to change the unit count | |
if ($targetUnitCount -ne $currentUnitCount) { | |
Write-Host "Scaling resource to unit count: " $targetUnitCount | |
# Change the resource unit count | |
$signalRResource.Sku.Capacity = $targetUnitCount | |
$signalRResource | Set-AzResource -Force | |
} else { | |
Write-Host "Not scaling as resource is already at the optimum unit count: " $currentUnitCount | |
} | |
} else { | |
Write-Host "Can't scale as resource is not on a scalable plan: " $signalRResource.Sku.Name | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment