Blog Post

Azure Database Support Blog
3 MIN READ

Auto scale up/down the Managed instance

amanda_ibrahim's avatar
Sep 20, 2022

Request:

If the customer needs to configure auto scaling for SQL Managed Instance, where the vCores can be increase and decrease automatically on specific time.

 

Solution:

You may take a look for this blog where it has a full example but for Azure SQL DB, you may customize it according to your needs:
               How-to auto-scale Azure SQL Databases - Microsoft Tech Community

 

Or you can follow the solution provided below:

Find below the steps you need to follow to create a Runbook to change the properties of the Managed instance, kindly note that this is a sample to help you out to set a base for your request then you can customize it according to your business needs.

 

The PowerShell command to get the Managed Instance information and to update the Managed Instance properties are:

 

1- Create a runbook with below proprieties:

 

2- Be sure that the AZ.account Module is added to the Automation account:

 

3- Then copy and paste the below PowerShell code:

 

param(
[parameter(Mandatory=$false)]
[string] $environmentName = "AzureCloud",

[parameter(Mandatory=$true)]
[string] $resourceGroupName,

[parameter(Mandatory=$false)]
[string] $azureRunAsConnectionName = "AzureRunAsConnection",

[parameter(Mandatory=$true)]
[string] $MIName,

[parameter(Mandatory=$false)]
[string] $defaultEdition = "GeneralPurpose",

[parameter(Mandatory=$false)]
[string] $defaultvCores = "4",

[parameter(Mandatory=$false)]
[string] $defaultStorageSizeInGB = "32",

[parameter(Mandatory=$false)]
[string] $defaultComputeGeneration = "Gen5"

)

filter timestamp {"[$(Get-Date -Format G)]: $_"}
Write-Output "Script started." | timestamp

#Authenticate with Azure Automation Run As account (service principal)
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

"Logging in to Azure..."
Connect-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint

Write-Output "Authenticated with Automation Run As Account." | timestamp
}
catch
{
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}

# Get the MI object
try
{
$sqlMI = Get-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName
Write-Output "MI name: $($sqlMI.ManagedInstanceName)" | timestamp
if ($sqlMI.ManagedInstanceName -ne "")
{
Write-Output "Current MI vCores: $($sqlMI.VCores), Storage: $($sqlMI.StorageSizeInGB)" | timestamp

Write-Output "---> Scaling schedule found. Check if current edition/tier is matching..." | timestamp
if($sqlMI.VCores -ne $defaultvCores -or $sqlMI.StorageSizeInGB -ne $defaultStorageSizeInGB)
{
Write-Output "--- ---> vCores and/or Storage Size are different. Changing!" | timestamp
Set-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName -VCore $defaultvCores -StorageSizeInGB $defaultStorageSizeInGB -ComputeGeneration $defaultComputeGeneration -Edition $defaultEdition -Force -Confirm:$false | out-null

Write-Output "Change to vCores/Storage size as specified in scaling schedule initiated..." | timestamp

$sqlMI = Get-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName
Write-Output "Current MI vCores: $($sqlMI.VCores), Storage: $($sqlMI.StorageSizeInGB)" | timestamp
}
else
{
Write-Output "Current MI vCores and/or Sotrage size matches the scaling schedule already. Exiting..." | timestamp
}
}
else{
Write-Error "Could not retrieve MI details" | timestamp
}
}
catch
{
Write-Error -Message $_.Exception
throw $_.Exception

}
Write-Output "Script finished." | timestamp

 

 

4- Run the script and pass the values of the Resource group and Managed instance name on the below highlighted parameters:

 

5- You should have a result similar to the below if the operation finished successfully, also you should expect the MI to be updated:

 

 

6- You can schedule this Job following the steps on the below link:

               Manage schedules in Azure Automation | Microsoft Docs

 


Note:

Please be aware that the scaling operation could take a while depending on the amount of data you have across all databases in the Managed Instance.

For more information refer to Management operations overview - Azure SQL Managed Instance | Microsoft Docs

Updated Sep 20, 2022
Version 2.0

4 Comments

  • Thanks for sharing the updated script. However, it gives me the below error. Any idea what's the reason?

     

    mCannot find the Azure Active Directory object
         | '<<<<<my email address>>>>>>>'. Please make
         | sure that the user or group or application you are authorizing
         | is registered in the current subscription's Azure Active
         | directory. To get a list of Azure Active Directory groups use
         | Get-AzADGroup, or to get a list of Azure Active Directory
         | users use Get-AzADUser or to get a list of Azure Active
         | Directory applications use Get-AzADApplication

     

  • Alan_Niedelman's avatar
    Alan_Niedelman
    Copper Contributor

    It appears to be working but it's not actually scaling the Managed Instance. Ran Set-AzSqlInstance comand with same the parameters from powershell without issue.

    [8/10/2023 6:46:31 PM]: MI name: xxxxxxx
    [8/10/2023 6:46:31 PM]: Current MI vCores: 8, Storage: 1024
    [8/10/2023 6:46:31 PM]: ---> Scaling schedule found. Check if current edition/tier is matching... 
    [8/10/2023 6:46:31 PM]: --- ---> vCores and/or Storage Size are different. Changing!
    [8/10/2023 6:46:33 PM]: Change to vCores/Sotrage size as specified in scaling schedule initiated...
    [8/10/2023 6:46:33 PM]: Current MI vCores: 8, Storage: 1024
    [8/10/2023 6:46:33 PM]: Script finished.

     

  • Since run as account will be deprecated soon:

     

    then you can customize this runbook to use Managed identity for authentication Tutorial - Create a PowerShell Workflow runbook in Azure Automation | Microsoft Learn.

     

    If you have the runbook already exists then you can follow the steps in this link to migrate to Managed identity Migrate from a Run As account to Managed identities | Microsoft Learn, or you can create a new runbook with Managed identity and then you can assign the required roles for the runbook at Subscription level, below is a screenshot of the role permission from my lab:

     

    below is updated script using System identity instead of run as account:

    param(
    [parameter(Mandatory=$false)]
    [string] $environmentName = "AzureCloud",   

    [parameter(Mandatory=$true)]
    [string] $resourceGroupName,

    [parameter(Mandatory=$true)]
    [string] $MIName,

    [parameter(Mandatory=$false)]
    [string] $defaultEdition = "GeneralPurpose",

    [parameter(Mandatory=$false)]
    [string] $defaultvCores = "4",

    [parameter(Mandatory=$false)]
    [string] $defaultStorageSizeInGB = "32",

    [parameter(Mandatory=$false)]
    [string] $defaultComputeGeneration = "Gen5"

    )

    filter timestamp {"[$(Get-Date -Format G)]: $_"}
    Write-Output "Script started." | timestamp

    try
    {

    # Ensures you do not inherit an AzContext in your runbook
    Disable-AzContextAutosave -Scope Process

    # Connect to Azure with system-assigned managed identity
    Connect-AzAccount -Identity

    # set and store context
    $AzureContext = Set-AzContext –SubscriptionId "put your SubscriptionId here"   

    Write-Output "Authenticated with Managed identity."  | timestamp
    }
    catch 
    {
        if (!$AzureContext)
            {
                $ErrorMessage = "Connection not found."
                    throw $ErrorMessage
                } else{
                    Write-Error -Message $_.Exception
                    throw $_.Exception
                }
    }

    # Get the MI object
    try
    {
        $sqlMI = Get-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName
        Write-Output "MI name: $($sqlMI.ManagedInstanceName)" | timestamp
        if ($sqlMI.ManagedInstanceName -ne "")
        {
            Write-Output "Current MI vCores: $($sqlMI.VCores), Storage: $($sqlMI.StorageSizeInGB)" | timestamp

                Write-Output "---> Scaling schedule found. Check if current edition/tier is matching..." | timestamp
                if($sqlMI.VCores -ne $defaultvCores -or $sqlMI.StorageSizeInGB -ne $defaultStorageSizeInGB)
                {
                    Write-Output "--- ---> vCores and/or Storage Size are different. Changing!" | timestamp
                    Set-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName -VCore $defaultvCores -StorageSizeInGB $defaultStorageSizeInGB -ComputeGeneration $defaultComputeGeneration -Edition $defaultEdition -Force -Confirm:$false | out-null

                    Write-Output "Change to vCores/Sotrage size as specified in scaling schedule initiated..." | timestamp
                    
                    $sqlMI = Get-AzSqlInstance -Name $MIName -ResourceGroupName $ResourceGroupName
                    Write-Output "Current MI vCores: $($sqlMI.VCores), Storage: $($sqlMI.StorageSizeInGB)" | timestamp
                }
                else
                {
                    Write-Output "Current MI vCores and/or Sotrage size matches the scaling schedule already. Exiting..." | timestamp
                }
        }
        else{
            Write-Error "Could not retrieve MI details" | timestamp
        }
    }
    catch 
    {
        Write-Error -Message $_.Exception
        throw $_.Exception
            
    }
    Write-Output "Script finished." | timestamp

     

  • Prakruthi2290's avatar
    Prakruthi2290
    Copper Contributor

    Hi Amanda ,

     

    I am getting one error:

    Error: Resource Group not found.

    I found another ‘service bus Namespace’ name that is similar when I searched for the resource group name.

     

    Need your help