项目作者: azureautomation

项目描述 :
Vertically scale an Azure SQL Database up or down according to a schedule using Azure Automation.
高级语言: PowerShell
项目地址: git://github.com/azureautomation/azure-sql-database-scale-using-scheduled-autoscaling.git


Azure SQL Database - Scale using scheduled autoscaling

This Azure Automation runbook enables vertically scaling of an Azure SQL Database according to a schedule. Autoscaling based on a schedule allows you to scale your solution according to predictable resource demand. For example you could require a high capacity
(e.g. P2) on Monday during peak hours, while the rest of the week the traffic is decreased allowing you to scale down (e.g. P1). Outside business hours and during weekends you could then scale down further to a minimum (e.g. S0). This runbook can be scheduled
to run hourly. The code checks the scalingSchedule parameter to decide if scaling needs to be executed, or if the database is in the desired state already and no work needs to be done. The script is Timezone aware.

jorgklein.com for more information and a step-by-step setup guide

<#

.SYNOPSIS

  1. Vertically scale an Azure SQL Database up or down according to a
  2. schedule using Azure Automation.

.DESCRIPTION

  1. This Azure Automation runbook enables vertically scaling of
  2. an Azure SQL Database according to a schedule. Autoscaling based
  3. on a schedule allows you to scale your solution according to
  4. predictable resource demand. For example you could require a
  5. high capacity (e.g. P2) on Monday during peak hours, while the rest
  6. of the week the traffic is decreased allowing you to scale down
  7. (e.g. P1). Outside business hours and during weekends you could then
  8. scale down further to a minimum (e.g. S0). This runbook
  9. can be scheduled to run hourly. The code checks the
  10. scalingSchedule parameter to decide if scaling needs to be
  11. executed, or if the database is in the desired state already and
  12. no work needs to be done. The script is Timezone aware.

.PARAMETER resourceGroupName

  1. Name of the resource group to which the database server is
  2. assigned.

.PARAMETER azureRunAsConnectionName

  1. Azure Automation Run As account name. Needs to be able to access
  2. the $serverName.

.PARAMETER serverName

  1. Azure SQL Database server name.

.PARAMETER databaseName

  1. Azure SQL Database name (case sensitive).

.PARAMETER scalingSchedule

  1. Database Scaling Schedule. It is possible to enter multiple
  2. comma separated schedules: [{},{}]
  3. Weekdays start at 0 (sunday) and end at 6 (saturday).
  4. If the script is executed outside the scaling schedule time slots
  5. that you defined, the defaut edition/tier (see below) will be
  6. configured.

.PARAMETER scalingScheduleTimeZone

  1. Time Zone of time slots in $scalingSchedule.
  2. Available time zones: [System.TimeZoneInfo]::GetSystemTimeZones().

.PARAMETER defaultEdition

  1. Azure SQL Database Edition that wil be used outside the slots
  2. specified in the scalingSchedule paramater value.
  3. Example values: Basic, Standard, Premium RS, Premium.
  4. For more information on editions/tiers levels,
  5. http://msdn.microsoft.com/en-us/library/azure/dn741336.aspx

.PARAMETER defaultTier

  1. Azure SQL Database Tier that wil be used outside the slots
  2. specified in the scalingSchedule paramater value.
  3. Example values: Basic, S0, S1, S2, S3, PRS1, PRS2, PRS4,
  4. PRS6, P1, P2, P4, P6, P11, P15.

.EXAMPLE

  1. -resourceGroupName myResourceGroup
  2. -azureRunAsConnectionName AzureRunAsConnection
  3. -serverName myserver
  4. -databaseName myDatabase
  5. -scalingSchedule [{WeekDays:[1], StartTime:'06:59:59',
  6. StopTime:'17:59:59', Edition: 'Premium', Tier: 'P2'},
  7. {WeekDays:[2,3,4,5], StartTime:'06:59:59',
  8. StopTime:'17:59:59', Edition: 'Premium', Tier: 'P1'}]
  9. -scalingScheduleTimeZone W. Europe Standard Time
  10. -defaultEdition Standard
  11. -defaultTier S0

.NOTES

  1. Author: Jorg Klein
  2. Last Update: 18/09/2017

>

param(

[parameter(Mandatory=$true)]

[string] $resourceGroupName,

[parameter(Mandatory=$true)]

[string] $azureRunAsConnectionName,

[parameter(Mandatory=$true)]

[string] $serverName,

[parameter(Mandatory=$true)]

[string] $databaseName,

[parameter(Mandatory=$true)]

[string] $scalingSchedule,

[parameter(Mandatory=$true)]

[string] $scalingScheduleTimeZone,

[parameter(Mandatory=$true)]

[string] $defaultEdition,

[parameter(Mandatory=$true)]

[string] $defaultTier

)

Write-Output ‘Script started.’

Authenticate with Azure Automation Run As account (service principal)

$runAsConnectionProfile = Get-AutomationConnection `

-Name $azureRunAsConnectionName

Add-AzureRmAccount -ServicePrincipal `

-TenantId $runAsConnectionProfile.TenantId `

-ApplicationId $runAsConnectionProfile.ApplicationId `

-CertificateThumbprint ` $runAsConnectionProfile.CertificateThumbprint | Out-Null

Write-Output ‘Authenticated with Automation Run As Account.’

Get current date/time and convert to $scalingScheduleTimeZone

$stateConfig = $scalingSchedule | ConvertFrom-Json

$startTime = Get-Date

Write-Output ‘Azure Automation local time: $startTime.’

$toTimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById($scalingScheduleTimeZone)

Write-Output ‘Time zone to convert to: $toTimeZone.’

$newTime = [System.TimeZoneInfo]::ConvertTime($startTime, $toTimeZone)

Write-Output ‘Converted time: $newTime.’

$startTime = $newTime

Get current day of week, based on converted start time

$currentDayOfWeek = Int.DayOfWeek

Write-Output ‘Current day of week: $currentDayOfWeek.’

Get the scaling schedule for the current day of week

$dayObjects = $stateConfig | Where-Object {$_.WeekDays -contains $currentDayOfWeek } `

|Select-Object Edition, Tier, `

@{Name=’StartTime’; Expression = {[datetime]::ParseExact($_.StartTime,’HH:mm:ss’, [System.Globalization.CultureInfo]::InvariantCulture)}}, `

@{Name=’StopTime’; Expression = {[datetime]::ParseExact($_.StopTime,’HH:mm:ss’, [System.Globalization.CultureInfo]::InvariantCulture)}}

Get the database object

$sqlDB = Get-AzureRmSqlDatabase `

-ResourceGroupName $resourceGroupName `

-ServerName $serverName `

-DatabaseName $databaseName

Write-Output ‘DB name: $($sqlDB.DatabaseName)’

Write-Output ‘Current DB status: $($sqlDB.Status), edition: $($sqlDB.Edition), tier: $($sqlDB.CurrentServiceObjectiveName)’

if($dayObjects -ne $null) { # Scaling schedule found for this day

  1. # Get the scaling schedule for the current time. If there is more than one available, pick the first
  2. $matchingObject = $dayObjects | Where-Object { ($startTime -ge $_.StartTime) -and ($startTime -lt $_.StopTime) } | Select-Object -First 1
  3. if($matchingObject -ne $null)
  4. {
  5. Write-Output 'Scaling schedule found. Check if current edition & tier is matching...'
  6. if($sqlDB.CurrentServiceObjectiveName -ne $matchingObject.Tier -or $sqlDB.Edition -ne $matchingObject.Edition)
  7. {
  8. Write-Output 'DB is not in the edition and/or tier of the scaling schedule. Changing!'
  9. $sqlDB | Set-AzureRmSqlDatabase -Edition $matchingObject.Edition -RequestedServiceObjectiveName $matchingObject.Tier | out-null
  10. Write-Output 'Change to edition/tier as specified in scaling schedule initiated...'
  11. $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName
  12. Write-Output 'Current DB status: $($sqlDB.Status), edition: $($sqlDB.Edition), tier: $($sqlDB.CurrentServiceObjectiveName)'
  13. }
  14. else
  15. {
  16. Write-Output 'Current DB tier and edition matches the scaling schedule already. Exiting...'
  17. }
  18. }
  19. else { # Scaling schedule not found for current time
  20. Write-Output 'No matching scaling schedule time slot for this time found. Check if current edition/tier matches the default...'
  21. if($sqlDB.CurrentServiceObjectiveName -ne $defaultTier -or $sqlDB.Edition -ne $defaultEdition)
  22. {
  23. Write-Output 'DB is not in the default edition and/or tier. Changing!'
  24. $sqlDB | Set-AzureRmSqlDatabase -Edition $defaultEdition -RequestedServiceObjectiveName $defaultTier | out-null
  25. Write-Output 'Change to default edition/tier initiated.'
  26. $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName
  27. Write-Output 'Current DB status: $($sqlDB.Status), edition: $($sqlDB.Edition), tier: $($sqlDB.CurrentServiceObjectiveName)'
  28. }
  29. else
  30. {
  31. Write-Output 'Current DB tier and edition matches the default already. Exiting...'
  32. }
  33. }

}

else # Scaling schedule not found for this day

{

  1. Write-Output 'No matching scaling schedule for this day found. Check if current edition/tier matches the default...'
  2. if($sqlDB.CurrentServiceObjectiveName -ne $defaultTier -or $sqlDB.Edition -ne $defaultEdition)
  3. {
  4. Write-Output 'DB is not in the default edition and/or tier. Changing!'
  5. $sqlDB | Set-AzureRmSqlDatabase -Edition $defaultEdition -RequestedServiceObjectiveName $defaultTier | out-null
  6. Write-Output 'Change to default edition/tier initiated.'
  7. $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName
  8. Write-Output 'Current DB status: $($sqlDB.Status), edition: $($sqlDB.Edition), tier: $($sqlDB.CurrentServiceObjectiveName)'
  9. }
  10. else
  11. {
  12. Write-Output 'Current DB tier and edition matches the default already. Exiting...'
  13. }

}

Write-Output ‘Script finished.’

TechNet gallery is retiring! This script was migrated from TechNet script center to GitHub by Microsoft Azure Automation product group. All the Script Center fields like Rating, RatingCount and DownloadCount have been carried over to Github as-is for the migrated scripts only. Note : The Script Center fields will not be applicable for the new repositories created in Github & hence those fields will not show up for new Github repositories.