다음을 통해 공유


Azure Automation: Scale-Down VM Size

Introduction

The Azure cloud offers a lot of services to make our daily work easier. In this post, we will read about an ordinary reflection for IT/DevOps departments, and to build our solution we use Logic Apps and Automation Account services.

Case

The main case is to automatically scale-down the VM size in a case an employee deployed a costly VM instance.

Prerequisites

  • A valid Azure Subscription
  • Register at the subscription the Resource Provider "Microsoft.EventGrid"

The Deployments

For the demo purposes, we will deploy Azure Logic Apps and an Azure Automation Account.

To begin with, from the left-hand sidebar, click All Services, type Automation in the search box and select Automation Accounts.

Select +Add or Create automation account, to begin

On the Add Automation Account form, type a unique Name for the automation account, select a valid subscription and a Resource group, the location should be the same where the resource group created and then click Create.

Create the Run book

The Automation account has been created, and the next step is to create the Runbook. To do this from the left-hand side bar we select Process Automation - Runbooks - + Create a runbook.

param
(
    [Parameter(Mandatory = $true)]
    [string]$ResourceGroupName
)
$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
}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}
# Get Virtual Machine Name and Size To Proceed With The Checks
#$ResourceGroupName = "AzureAutomationRG"
$VMName = (Get-AzVM -ResourceGroupName $ResourceGroupName).Name
$VMSize = (Get-AzVM -ResourceGroupName $ResourceGroupName).HardwareProfile
# If the size of the VM is not Standard_F4s,then resize the size to Standard_F4s.
if ($VMSize -eq "Standard_F4s"){
write-host "VM is allready a Standard_F4s"}
else {
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName
$vm.HardwareProfile.VmSize = "Standard_F4s"
Update-AzVM -VM $vm -ResourceGroupName $ResourceGroupName
write-host The Virtual Machine $vm has been resized to "Standard_F4s"
}

Create A Blank Logic App

From the left-hand main blade select **Create a resource, **search for Logic App and then click Create.

Next, type the useful information (Subscription, Resource Group, Logic App name, Location) about the Logic App and then type Review + Create

After the Logic App deployment finish, we start to build the flow on the Logic App designer.

Add the Event Grid Trigger

To begin with, select to create a Blank Logic App.

In the search box type "Event Grid" and select the trigger "When a resource event occurs" to start the logic app flow building.

First, we signed in the trigger with Azure credentials, and provide all the necessary fields as the image below shows.

At the next actions, we will initialize four different variables (Subject, Virtual Machine Name, Resource Group, Resource).

Repeat the step above also for the other three variables.

After we added actions to initialize the variables we add a Parse JSON action

{
    "items": {
        "properties": {
            "data": {
                "properties": {
                    "authorization": {
                        "properties": {
                            "action": {
                                "type": "string"
                            },
                            "evidence": {
                                "properties": {
                                    "role": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            },
                            "scope": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "claims": {
                        "properties": {
                            "aio": {
                                "type": "string"
                            },
                            "appid": {
                                "type": "string"
                            },
                            "appidacr": {
                                "type": "string"
                            },
                            "aud": {
                                "type": "string"
                            },
                            "exp": {
                                "type": "string"
                            },
                            "groups": {
                                "type": "string"
                            },
                            "http://schemas.microsoft.com/claims/authnclassreference": {
                                "type": "string"
                            },
                            "http://schemas.microsoft.com/claims/authnmethodsreferences": {
                                "type": "string"
                            },
                            "http://schemas.microsoft.com/identity/claims/objectidentifier": {
                                "type": "string"
                            },
                            "http://schemas.microsoft.com/identity/claims/scope": {
                                "type": "string"
                            },
                            "http://schemas.microsoft.com/identity/claims/tenantid": {
                                "type": "string"
                            },
                            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname": {
                                "type": "string"
                            },
                            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": {
                                "type": "string"
                            },
                            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": {
                                "type": "string"
                            },
                            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname": {
                                "type": "string"
                            },
                            "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn": {
                                "type": "string"
                            },
                            "iat": {
                                "type": "string"
                            },
                            "ipaddr": {
                                "type": "string"
                            },
                            "iss": {
                                "type": "string"
                            },
                            "name": {
                                "type": "string"
                            },
                            "nbf": {
                                "type": "string"
                            },
                            "puid": {
                                "type": "string"
                            },
                            "rh": {
                                "type": "string"
                            },
                            "uti": {
                                "type": "string"
                            },
                            "ver": {
                                "type": "string"
                            },
                            "wids": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "correlationId": {
                        "type": "string"
                    },
                    "operationName": {
                        "type": "string"
                    },
                    "resourceProvider": {
                        "type": "string"
                    },
                    "resourceUri": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string"
                    },
                    "subscriptionId": {
                        "type": "string"
                    },
                    "tenantId": {
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "dataVersion": {
                "type": "string"
            },
            "eventTime": {
                "type": "string"
            },
            "eventType": {
                "type": "string"
            },
            "id": {
                "type": "string"
            },
            "metadataVersion": {
                "type": "string"
            },
            "subject": {
                "type": "string"
            },
            "topic": {
                "type": "string"
            }
        },
        "required": [
            "subject",
            "eventType",
            "id",
            "data",
            "dataVersion",
            "metadataVersion",
            "eventTime",
            "topic"
        ],
        "type": "object"
    },
    "type": "array"
}

Add a For each Action with variables

The next action in the flow is to add a "For each" action and within it to add the next actions. Specifically the first action we add into the "For each" is the "Set variable" action

 

Add a Compose Action

Add a compose action to separate the string to separate values.



      Subject Variable Value: /subscriptions/#######-####-####-####-###########/resourceGroups/DemoScaleDownVmRG/providers/Microsoft.Compute/virtualMachines/demovm  

To achieve this, we need to write a simple expression using the split function, as the image below shows.

split(variables('Subject'),'/')

The result after the Logic App run would be the below

[
  "",
  "subscriptions",
  "#######-####-####-####-###########",
  "resourceGroups",
  "DemoScaleDownVmRG",
  "providers",
  "Microsoft.Compute",
  "virtualMachines",
  "demovm"
]

Now that successful split into several parts can proceed with the rest variables.

For the "Resource" variable we type the expression,

outputs('Compose_Variable_Subject')[7]

to get the "Virtual Machine Name" type the expression,

outputs('Compose_Variable_Subject')[8]


and final, the last variable "Resource Group" type,

outputs('Compose_Variable_Subject')[4]

Add A Switch Action

From the action list select to add a Switch

Add an Automation Account Create job action

Last but not least step we add the automation account "Create job" action, this would execute the job with the PowerShell script we created in the Automation Account step.

In the end, the deployment should be like the one in the image below.

Test the Logic App Workflow

The video file below shows how the workflow works. We have deployed a new Azure VM with "Standard_D16as_v4" size, and after the workflow successful run the size of the virtual machines changed to "Standard_F4s".

View

See Also