Giter Club home page Giter Club logo

azure-sql-database-scale-using-scheduled-autoscaling's Introduction

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   

    Vertically scale an Azure SQL Database up or down according to a 

    schedule using Azure Automation.    

   

.DESCRIPTION   

    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.

.PARAMETER resourceGroupName

    Name of the resource group to which the database server is 

    assigned.

.PARAMETER azureRunAsConnectionName

    Azure Automation Run As account name. Needs to be able to access

    the $serverName.

 .PARAMETER serverName  

    Azure SQL Database server name.

       

.PARAMETER databaseName   

    Azure SQL Database name (case sensitive).

.PARAMETER scalingSchedule

    Database Scaling Schedule. It is possible to enter multiple 

    comma separated schedules: [{},{}]

    Weekdays start at 0 (sunday) and end at 6 (saturday).

    If the script is executed outside the scaling schedule time slots

    that you defined, the defaut edition/tier (see below) will be 

    configured.

.PARAMETER scalingScheduleTimeZone

    Time Zone of time slots in $scalingSchedule. 

    Available time zones: [System.TimeZoneInfo]::GetSystemTimeZones().

.PARAMETER defaultEdition

    Azure SQL Database Edition that wil be used outside the slots 

    specified in the scalingSchedule paramater value.

    Example values: Basic, Standard, Premium RS, Premium.

    For more information on editions/tiers levels, 

    http://msdn.microsoft.com/en-us/library/azure/dn741336.aspx 

 

.PARAMETER defaultTier   

    Azure SQL Database Tier that wil be used outside the slots 

    specified in the scalingSchedule paramater value.

    Example values: Basic, S0, S1, S2, S3, PRS1, PRS2, PRS4, 

    PRS6, P1, P2, P4, P6, P11, P15.

.EXAMPLE

        -resourceGroupName myResourceGroup

        -azureRunAsConnectionName AzureRunAsConnection

        -serverName myserver

        -databaseName myDatabase

        -scalingSchedule [{WeekDays:[1], StartTime:'06:59:59', 

            StopTime:'17:59:59', Edition: 'Premium', Tier: 'P2'},

            {WeekDays:[2,3,4,5], StartTime:'06:59:59', 

            StopTime:'17:59:59', Edition: 'Premium', Tier: 'P1'}]

        -scalingScheduleTimeZone W. Europe Standard Time

        -defaultEdition Standard

        -defaultTier S0

   

.NOTES   

    Author: Jorg Klein

    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

    # Get the scaling schedule for the current time. If there is more than one available, pick the first

    $matchingObject = $dayObjects | Where-Object { ($startTime -ge $.StartTime) -and ($startTime -lt $.StopTime) } | Select-Object -First 1

    if($matchingObject -ne $null)

    {

        Write-Output 'Scaling schedule found. Check if current edition & tier is matching...'

        if($sqlDB.CurrentServiceObjectiveName -ne $matchingObject.Tier -or $sqlDB.Edition -ne $matchingObject.Edition)

        {

            Write-Output 'DB is not in the edition and/or tier of the scaling schedule. Changing!'

            $sqlDB | Set-AzureRmSqlDatabase -Edition $matchingObject.Edition -RequestedServiceObjectiveName $matchingObject.Tier | out-null

            Write-Output 'Change to edition/tier as specified in scaling schedule initiated...'

            $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName

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

        } 

        else 

        {

            Write-Output 'Current DB tier and edition matches the scaling schedule already. Exiting...'

        }

    }

    else { # Scaling schedule not found for current time

        Write-Output 'No matching scaling schedule time slot for this time found. Check if current edition/tier matches the default...'

        if($sqlDB.CurrentServiceObjectiveName -ne $defaultTier -or $sqlDB.Edition -ne $defaultEdition)

        {

            Write-Output 'DB is not in the default edition and/or tier. Changing!'

            $sqlDB | Set-AzureRmSqlDatabase -Edition $defaultEdition -RequestedServiceObjectiveName $defaultTier | out-null

            Write-Output 'Change to default edition/tier initiated.'

            $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName

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

        }

        else

        {

            Write-Output 'Current DB tier and edition matches the default already. Exiting...'

        }

    }

}

else # Scaling schedule not found for this day

{

    Write-Output 'No matching scaling schedule for this day found. Check if current edition/tier matches the default...'

    if($sqlDB.CurrentServiceObjectiveName -ne $defaultTier -or $sqlDB.Edition -ne $defaultEdition)

    {

        Write-Output 'DB is not in the default edition and/or tier. Changing!'

        $sqlDB | Set-AzureRmSqlDatabase -Edition $defaultEdition -RequestedServiceObjectiveName $defaultTier | out-null

        Write-Output 'Change to default edition/tier initiated.'

        $sqlDB = Get-AzureRmSqlDatabase -ResourceGroupName $resourceGroupName -ServerName $serverName -DatabaseName $databaseName

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

    }

    else

    {

        Write-Output 'Current DB tier and edition matches the default already. Exiting...'

    }

}

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.

azure-sql-database-scale-using-scheduled-autoscaling's People

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

azure-sql-database-scale-using-scheduled-autoscaling's Issues

getting failed job

With this parameters...

  • RESOURCEGROUPNAME: mydb-rg
  • DATABASENAME: mydb
  • SERVERNAME: myserver
  • DEFAULTEDITION: Standard
  • DEFAULTTIER: S0
  • SCALINGSCHEDULE: [{WeekDays:[1,2,3,4,5], StartTime:"08:00:00", StopTime:"20:00:00", Edition: Standard, Tier: s3}]
  • other options: default

I am getting this exception...

At line:138 char:93 + ... = {[datetime]::ParseExact(($startTime.ToString("yyyy:MM:dd")+�:�+ ... + ~ You must provide a value expression following the '+' operator. At line:138 char:93 + ... Exact(($startTime.ToString("yyyy:MM:dd")+�:�+$_.StartTime),"yyyy: ... + ~~~~~~~~~~~~~~~~~~~~ Unexpected token '�:�+$_.StartTime' in expression or statement. At line:138 char:93 + ... = {[datetime]::ParseExact(($startTime.ToString("yyyy:MM:dd")+�:�+ ... + ~ Missing closing ')' in expression. At line:138 char:93 + ... = {[datetime]::ParseExact(($startTime.ToString("yyyy:MM:dd")+�:�+ ... + ~ Missing ')' in method call. At line:138 char:34 + @{Name="StartTime"; Expression = {[datetime]::ParseExact(($startTime. ... + ~ Missing closing '}' in statement block or type definition. At line:138 char:113 + ... Exact(($startTime.ToString("yyyy:MM:dd")+�:�+$_.StartTime),"yyyy: ... + ~ The hash literal was incomplete. At line:138 char:113 + ... xact(($startTime.ToString("yyyy:MM:dd")+�:�+$_.StartTime),"yyyy:M ... + ~ Unexpected token ')' in expression or statement. At line:138 char:190 + ... HH:mm:ss", [System.Globalization.CultureInfo]::InvariantCulture)}}, ` + ~ Unexpected token ')' in expression or statement. At line:138 char:191 + ... HH:mm:ss", [System.Globalization.CultureInfo]::InvariantCulture)}}, ` + ~ Unexpected token '}' in expression or statement. At line:138 char:192 + ... HH:mm:ss", [System.Globalization.CultureInfo]::InvariantCulture)}}, ` + ~ Unexpected token '}' in expression or statement. Not all parse errors were reported. Correct the reported errors and try again.

I believe SCALINGSCHEDULE variable is not needed due to schedule resources shared. Can you please help?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.