%3CLINGO-SUB%20id%3D%22lingo-sub-1181125%22%20slang%3D%22en-US%22%3EAuto%20scale%20Azure%20Spring%20Cloud%20with%20Azure%20Monitor%20and%20Azure%20Automation%20Runbooks%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1181125%22%20slang%3D%22en-US%22%3E%3CH3%20id%3D%22toc-hId-1088969716%22%20id%3D%22toc-hId-1088969716%22%3E%3CU%3E8%2F27%2F2020%20update%3A%20Autoscale%20is%20now%20a%20built-in%20feature%20in%20Azure%20Spring%20Cloud!%20See%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fspring-cloud%2Fspring-cloud-tutorial-setup-autoscale%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3Ethis%20article%3C%2FA%3E%20to%20get%20started.%20You%20can%20still%20use%20steps%20described%20in%20this%20blog%20to%20performance%20test%20for%20autoscale%20and%20use%20the%20same%20generic%20approach%20with%20other%20Azure%20services.%3C%2FU%3E%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--718484747%22%20id%3D%22toc-hId--718484747%22%3EIntroduction%3C%2FH3%3E%0A%3CP%3EAuto%20scale%20is%20an%20automation%20mechanism%20that%20scales%20resources%20for%20your%20apps%20based%20on%20a%20predefined%20set%20of%20conditions.%20Auto%20scale%20is%20a%20critical%20aspect%20of%20application%20lifecycle%20management%2C%20especially%20in%20a%20cloud%20computing%20environment%2C%20where%20you%20have%20vast%20amount%20of%20resources%20at%20disposal.%20With%20the%20right%20auto%20scale%20strategy%2C%20you%20can%20optimize%20your%20Azure%20bill%20and%20only%20pay%20for%20resources%20when%20you%20really%20need%20them.%20In%20this%20blog%20I%20will%20auto%20scale%20Azure%20Spring%20Cloud%20with%20Azure%20Monitor%20and%20Azure%20Automation%20Runbooks%20in%204%20steps.%20The%20methodology%20described%20here%20is%20a%20generic%20approach%20and%20will%20work%20with%20other%20Azure%20services%20as%20well.%20We%20will%20use%20the%20following%20components%20to%20build%20our%20automation%20and%20let%E2%80%99s%20cover%20some%20concepts%20first.%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EAzure%20Run%20As%20account%3A%20Azure%20automation%20account%20provides%20a%20container%20for%20your%20Azure%20Automation%20resources.%20When%20you%20create%20a%20Azure%20Run%20As%20account%2C%20it%20creates%20a%20new%20service%20principal%20in%20Azure%20Active%20Directory%20and%20assigns%20the%20Contributor%20role%20to%20this%20user%20at%20the%20subscription%20level.%20In%20our%20case%2C%20we%20will%20use%20the%20service%20principal%20created%20from%20the%20Azure%20Run%20As%20account%20to%20scale%20out%20apps.%3C%2FLI%3E%0A%3CLI%3EWebhook%3A%20Webhook%20is%20a%20http%20callback%20endpoint.%20We%20will%20use%20it%20when%20an%20alert%20is%20triggered.%3C%2FLI%3E%0A%3CLI%3EAlerts%20from%20Azure%20Monitor%3A%20Define%20alert%20conditions%20and%20actions%20based%20on%20resources%20consumed.%3C%2FLI%3E%0A%3CLI%3EPerformance%20testing%20from%20Application%20Insights%3A%20We%20will%20use%20performance%20testing%20from%20Application%20Insights%20to%20generate%20http%20load%20and%20trigger%20alerts.%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3EIn%20the%20automation%20flow%2C%20we%20will%20first%20generate%20http%20load%20from%20Application%20Insights.%20This%20will%20put%20pressure%20on%20our%20gateway%20service%20and%20increase%20App%20CPU%20consumption.%20Based%20on%20conditions%20defined%2C%20alerts%20will%20then%20be%20trigger%20and%20a%20webhook%20callback%20action%20is%20performance.%20The%20webhook%20will%20invoke%20an%20Azure%20Automation%20Runbook%2C%20which%20scales%20out%20our%20Spring%20Boot%20app.%3C%2FP%3E%0A%3CDIV%20id%3D%22tinyMceEditorSean_Li_0%22%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3CDIV%20id%3D%22tinyMceEditorSean_Li_1%22%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22flow.png%22%20style%3D%22width%3A%20984px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171952i0F47F44CD0445FA0%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22flow.png%22%20alt%3D%22flow.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%E2%80%99ll%20use%20Piggymetrics%20as%20our%20Spring%20Boot%20app.%20You%20can%20follow%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fspring-cloud%2Fspring-cloud-quickstart-launch-app-portal%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%22%3Einstructions%20here%3C%2FA%3E%20to%20create%20an%20Azure%20Spring%20Cloud%20instance%20and%20deploy%20Piggymetrics.%20Now%20let%E2%80%99s%20get%20started%20on%20building%20the%20automation.%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1769028086%22%20id%3D%22toc-hId-1769028086%22%3EStep%201%20%E2%80%93%20create%20an%20automation%20account%3C%2FH3%3E%0A%3CP%3EFrom%20the%20Azure%20marketplace%20search%20for%20%E2%80%9Cautomation%E2%80%9D.%20Pick%20yes%20to%20create%20an%20Azure%20Run%20As%20account%20in%20the%20service%20creation%20step.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%221.png%22%20style%3D%22width%3A%20464px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171953i365481D52924C868%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%221.png%22%20alt%3D%221.png%22%20%2F%3E%3C%2FSPAN%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--38426377%22%20id%3D%22toc-hId--38426377%22%3EStep%202%20%E2%80%93%20create%20automation%20runbook%3C%2FH3%3E%0A%3CP%3EOnce%20the%20automation%20account%20is%20created%2C%20head%20over%20to%20the%20process%20automation%20section%20of%20the%20automation%20account%20and%20click%20on%20runbooks.%20Create%20a%20runbook%20and%20pick%20PowerShell%20as%20the%20runbook%20type.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%222.png%22%20style%3D%22width%3A%20840px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171954i64B6E3A4F44AA051%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%222.png%22%20alt%3D%222.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3ECopy%20and%20paste%20the%20code%20snippet%20in%20the%20PowerShell%20editor.%3C%2FP%3E%0A%3CP%3E%3CCODE%3E%3CCODE%3E%3C%2FCODE%3E%3C%2FCODE%3E%3C%2FP%3E%0A%3CP%3Eparam%3C%2FP%3E%0A%3CP%3E(%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%5BParameter%26nbsp%3B(Mandatory%26nbsp%3B%3D%26nbsp%3B%24false)%5D%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%5Bobject%5D%26nbsp%3B%24WebhookData%3C%2FP%3E%0A%3CP%3E)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%23connect%26nbsp%3Bto%26nbsp%3BAzure%26nbsp%3Busing%26nbsp%3BAzure%26nbsp%3BRun%26nbsp%3BAs%26nbsp%3Baccount%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3BWrite-Output%26nbsp%3B%22Authenticating%26nbsp%3Bto%26nbsp%3BAzure%26nbsp%3Bwith%26nbsp%3Bservice%26nbsp%3Bprincipal%26nbsp%3Band%26nbsp%3Bcertificate%22%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24ConnectionAssetName%26nbsp%3B%3D%26nbsp%3B%22AzureRunAsConnection%22%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24servicePrincipalConnection%26nbsp%3B%3D%26nbsp%3BGet-AutomationConnection%26nbsp%3B-Name%26nbsp%3B%24ConnectionAssetName%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%22Logging%26nbsp%3Bin%26nbsp%3Bto%26nbsp%3BAzure...%22%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BConnect-AzAccount%26nbsp%3B%60%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B-ServicePrincipal%26nbsp%3B%60%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B-TenantId%26nbsp%3B%24servicePrincipalConnection.TenantId%26nbsp%3B%60%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B-ApplicationId%26nbsp%3B%24servicePrincipalConnection.ApplicationId%26nbsp%3B%60%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B-CertificateThumbprint%26nbsp%3B%24servicePrincipalConnection.CertificateThumbprint%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3Bif(-Not%26nbsp%3B%24WebhookData.RequestBody)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%7B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23allow%26nbsp%3Btest%26nbsp%3Bin%26nbsp%3Btest%26nbsp%3Bpane%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24WebhookData%3D(ConvertFrom-Json%26nbsp%3B-InputObject%26nbsp%3B%24WebhookData)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23convert%26nbsp%3Bwebhook%26nbsp%3Bdata%26nbsp%3Bto%26nbsp%3Ba%26nbsp%3BJson%26nbsp%3Bobject%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24WebhookData%3D(ConvertFrom-Json%26nbsp%3B-InputObject%26nbsp%3B%24WebhookData.RequestBody)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%7D%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3Belse%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%7B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23convert%26nbsp%3Bwebhook%26nbsp%3Bdata%26nbsp%3Bto%26nbsp%3Ba%26nbsp%3BJson%26nbsp%3Bobject%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24WebhookData%3D(ConvertFrom-Json%26nbsp%3B-InputObject%26nbsp%3B%24WebhookData.RequestBody)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%7D%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23retrieve%26nbsp%3Balert%26nbsp%3Bdata%26nbsp%3Bfrom%26nbsp%3Bwebhook%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24AlertContext%3D%24WebhookData.data.context%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23parse%26nbsp%3Bthe%26nbsp%3Bname%26nbsp%3Bof%26nbsp%3Bthe%26nbsp%3Bapp%26nbsp%3Bthat%26nbsp%3Btriggered%26nbsp%3Bthe%26nbsp%3Balert%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24AppName%26nbsp%3B%3D%26nbsp%3B%24AlertContext.condition.allof.dimensions%26nbsp%3B%7C%26nbsp%3Bwhere%26nbsp%3B%7B%24_.name%26nbsp%3B-eq%26nbsp%3B%22AppName%22%7D%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23appname%26nbsp%3Bis%26nbsp%3Bcase%26nbsp%3Bsensitive%26nbsp%3Bas%26nbsp%3Ba%26nbsp%3Bpart%26nbsp%3Bof%26nbsp%3Bthe%26nbsp%3BAzure%26nbsp%3Bresource%26nbsp%3BID.%26nbsp%3BAll%26nbsp%3Bmy%26nbsp%3Bapp%26nbsp%3Bnames%26nbsp%3Bare%26nbsp%3Blower%26nbsp%3Bcase.%26nbsp%3BIn%26nbsp%3Bsome%26nbsp%3Bcases%26nbsp%3BAlert%26nbsp%3Bwill%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23capitalize%26nbsp%3Bthe%26nbsp%3Bfirst%26nbsp%3Bletter%26nbsp%3Bof%26nbsp%3Bappname%26nbsp%3Bin%26nbsp%3Bthe%26nbsp%3Balert%26nbsp%3Bcontext.%26nbsp%3BMake%26nbsp%3Bsure%26nbsp%3Bthe%26nbsp%3Bcase%26nbsp%3Btype%26nbsp%3Bmatches%26nbsp%3Bwith%26nbsp%3Bthe%26nbsp%3Bname%26nbsp%3Bof%26nbsp%3Byour%26nbsp%3Bapp.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24AppName%26nbsp%3B%3D%26nbsp%3B%24AppName.value.ToLower()%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24resourceId%26nbsp%3B%3D%26nbsp%3B(%26nbsp%3B%24AlertContext.resourceId%26nbsp%3B%2B%26nbsp%3B'%2Fapps%2F'%26nbsp%3B%2B%26nbsp%3B%24AppName%26nbsp%3B%2B%26nbsp%3B'%2Fdeployments%2Fdefault')%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23scale%26nbsp%3Bthe%26nbsp%3Bapp%26nbsp%3Bout%26nbsp%3Bby%26nbsp%3Badding%26nbsp%3B1%26nbsp%3Bmore%26nbsp%3Bapp%26nbsp%3Binstance%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24Resource%26nbsp%3B%3D%26nbsp%3BGet-AzResource%26nbsp%3B-ResourceId%26nbsp%3B%24resourceId%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%23retrieve%26nbsp%3Bcurrent%26nbsp%3Binstance%26nbsp%3Bcount%26nbsp%3Band%26nbsp%3Bconvert%26nbsp%3Bit%26nbsp%3Bto%26nbsp%3Ba%26nbsp%3Bnumber%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24IC%26nbsp%3B%3D%26nbsp%3B%24Resource.Properties.deploymentSettings.instanceCount%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%5Bint%5D%24CurrentInstanceCount%26nbsp%3B%3D%26nbsp%3B%5Bconvert%5D%3A%3AToInt32(%24IC%2C%26nbsp%3B10)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24TargetInstanceCount%26nbsp%3B%3D%26nbsp%3B%24CurrentInstanceCount%26nbsp%3B%2B%26nbsp%3B1%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BWrite-Output%26nbsp%3B(%26nbsp%3B'Scaling%26nbsp%3B'%26nbsp%3B%2B%26nbsp%3B%24AppName.value%26nbsp%3B%2B%26nbsp%3B'%26nbsp%3Binstance%26nbsp%3Bcount%26nbsp%3Bfrom%26nbsp%3B'%26nbsp%3B%2B%26nbsp%3B%24CurrentInstanceCount%26nbsp%3B%2B'%26nbsp%3Bto%26nbsp%3B'%26nbsp%3B%2B%26nbsp%3B%24TargetInstanceCount)%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24Resource.Properties.deploymentSettings.instanceCount%3D%24TargetInstanceCount%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%24Resource%26nbsp%3B%7C%26nbsp%3BSet-AzResource%26nbsp%3B-Force%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3BWrite-Output%26nbsp%3B'Scaling%26nbsp%3Bcompleted'%3C%2FP%3E%0A%3CP%3E%3CCODE%3E%0A%3C%2FCODE%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ESave%20and%20publish%20the%20runbook.%3C%2FP%3E%0A%3CP%3ELastly%2C%20we%20need%20to%20import%20dependencies%20for%20the%20PowerShell%20modules%20used%20in%20the%20code%20snippet.%20Go%20back%20to%20the%20automation%20account%2C%20under%20modules%2C%20click%20on%20browse%20gallery%20and%20import%20Az.Accounts%20and%20Az.Resources.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%223.png%22%20style%3D%22width%3A%20924px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171957iB91A2B60B1FF29ED%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%223.png%22%20alt%3D%223.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--1845880840%22%20id%3D%22toc-hId--1845880840%22%3EStep%203%20%E2%80%93%20Add%20a%20webhook%3C%2FH3%3E%0A%3CP%3EFrom%20the%20overview%20menu%20of%20the%20runbook%2C%20click%20on%20Add%20webhook.%20An%20URL%20which%20includes%20a%20security%20token%20will%20be%20auto%20generated.%20%3CU%3EMake%20sure%20you%20copy%20this%20URL%20and%20save%20it%20somewhere%20safe%3C%2FU%3E%20as%20it%20will%20not%20be%20available%20to%20you%20once%20the%20webhook%20is%20created.%3C%2FP%3E%0A%3CP%3ELeave%20everything%20else%20as%20default%20in%20the%20parameters%20and%20run%20settings%20menu.%20Click%20on%20create%20to%20create%20the%20webhook.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%224.png%22%20style%3D%22width%3A%20524px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171958iAD1C1CAFCF60330C%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%224.png%22%20alt%3D%224.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-641631993%22%20id%3D%22toc-hId-641631993%22%3EStep%204%20%E2%80%93%20Add%20an%20alert%20and%20connect%20it%20with%20the%20webhook%3C%2FH3%3E%0A%3CP%3EAdd%20a%20new%20alert%20rule%20from%20Alerts%20under%20the%20Monitoring%20section%20of%20your%20Azure%20Spring%20Cloud%20service%20instance.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%225.png%22%20style%3D%22width%3A%20482px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171959iA73A8519B3D35CC2%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%225.png%22%20alt%3D%225.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3ESelect%20%E2%80%9CApp%20CPU%20Usage%20Percentage%20(Platform)%E2%80%9D%20under%20signal%20type.%3C%2FLI%3E%0A%3CLI%3ESelect%20all%20services%20in%20the%20app%20dimension%3C%2FLI%3E%0A%3CLI%3ESet%20the%20alert%20to%20go%20off%20when%20average%20consumption%20is%20greater%20than%205%25%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%226.png%22%20style%3D%22width%3A%20680px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171960i3C8E4FDCED5DC89D%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%226.png%22%20alt%3D%226.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3ECreate%20a%20new%20action%20group%20for%20the%20alert%20condition.%20Pick%20webhook%20in%20the%20action%20type%20and%20paste%20the%20webhook%20callback%20URI%20that%20you%20save%20in%20step%203.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%227.png%22%20style%3D%22width%3A%20844px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171961iE95B144BD70F859D%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%227.png%22%20alt%3D%227.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--1165822470%22%20id%3D%22toc-hId--1165822470%22%3EStep%204%20%E2%80%93%20Test%20auto%20scale%3C%2FH3%3E%0A%3CP%3ETo%20trigger%20the%20auto%20scale%20we%20will%20need%20to%20generate%20some%20load%20to%20get%20the%20average%20CPU%20consumption%20above%205%25.%20I%20will%20use%20Azure%20Application%20Insights%20for%20this%20task.%20Create%20an%20Application%20Insights%20instance%20from%20the%20Azure%20portal%20and%20click%20on%20performance%20testing%20under%20the%20configure%20menu.%20Click%20on%20new%20and%20choose%20manual%20test%20under%20test%20type.%20Copy%20and%20paste%20the%20public%20endpoint%20of%20the%20piggymetrics%20gateway%20app%20and%20Click%20on%20run%20test.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%228.png%22%20style%3D%22width%3A%20623px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171962i299F015F77C1BC5F%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%228.png%22%20alt%3D%228.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAfter%20the%20load%20test%20is%20complete%2C%20let%E2%80%99s%20head%20back%20to%20Metrics%20under%20the%20Monitoring%20section%20of%20our%20Azure%20Spring%20Cloud%20instance.%20We%20see%20our%20average%20App%20CPU%20usage%20crept%20up%20to%2010%25%20during%20the%20load%20test.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%229.png%22%20style%3D%22width%3A%20916px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171964i21ED2338E631C890%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%229.png%22%20alt%3D%229.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3ENext%20we%20will%20check%20recent%20jobs%20under%20our%20automation%20account%2C%20and%20we%20see%20a%20new%20job%20has%20completed.%20Click%20on%20the%20job%20entry%20in%20the%20table%20to%20see%20details%20of%20this%20job.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%2210.png%22%20style%3D%22width%3A%20688px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171965i276190DD6C5937E2%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%2210.png%22%20alt%3D%2210.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EYou%20can%20find%20the%20input%20of%20the%20webhook%20data%20from%20the%20input%20tab.%20You%20can%20copy%20this%20data%20and%20use%20it%20as%20the%20input%20parameter%20when%20customizing%20the%20auto%20scale%20script.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%2211.png%22%20style%3D%22width%3A%20815px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171966iBD72355389AD0E7C%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%2211.png%22%20alt%3D%2211.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EThe%20output%20tab%20shows%20output%20from%20the%20automation%20script%2C%20and%20you%20will%20see%20%E2%80%9CSet-AzResource%20%3A%20The%20operation%20failed%20because%20resource%20could%20not%20be%20de-serialized.%E2%80%9D%20Under%20the%20errors%20tab.%20You%20can%20ignore%20this%20message.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EFinally%2C%20go%20back%20to%20your%20Azure%20Spring%20Cloud%20instance%20and%20verify%20that%20the%20gateway%20service%20has%20been%20scaled%20out%20to%202%20instances.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%2212.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171968i08C945E3B76C532B%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%2212.png%22%20alt%3D%2212.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1321690363%22%20id%3D%22toc-hId-1321690363%22%3EClosing%20remarks%3C%2FH3%3E%0A%3CP%3ECongratulations%2C%20you%E2%80%99ve%20now%20set%20up%20auto%20scaling%20for%20you%20Azure%20Spring%20Cloud%20apps.%20Consider%20the%20following%20steps%20to%20take%20this%20setup%20for%20production.%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ETest%20and%20customize%20the%20automation%20script%20against%20your%20webhook%2C%20as%20your%20webhook%20input%20data%20may%20be%20different.%3C%2FLI%3E%0A%3CLI%3EFigure%20out%20the%20right%20auto%20scale%20strategy%20based%20on%20your%20usage%20patterns%2C%20and%20the%20types%20of%20resources%20consumed%20by%20your%20apps.%3C%2FLI%3E%0A%3CLI%3EFollow%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-monitor%2Fplatform%2Fautoscale-best-practices%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ebest%20practices%3C%2FA%3E%20for%20auto%20scale.%3C%2FLI%3E%0A%3CLI%3EFor%20advance%20load%20test%20scenarios%20you%20can%20use%20%3CA%20href%3D%22https%3A%2F%2Fgatling.io%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGatling%3C%2FA%3E.%20It%20requires%20programing%20in%20Scala%2C%20but%20you%20can%20record%20test%20actions%20and%20replay%20them%20in%20scripts%2C%20once%20you%20configure%20Gatling%20as%20your%20local%20proxy%20in%20the%20browser.%3C%2FLI%3E%0A%3C%2FUL%3E%3C%2FLINGO-BODY%3E
Microsoft

8/27/2020 update: Autoscale is now a built-in feature in Azure Spring Cloud! See this article to get started. You can still use steps described in this blog to performance test for autoscale and use the same generic approach with other Azure services.

 

Introduction

Auto scale is an automation mechanism that scales resources for your apps based on a predefined set of conditions. Auto scale is a critical aspect of application lifecycle management, especially in a cloud computing environment, where you have vast amount of resources at disposal. With the right auto scale strategy, you can optimize your Azure bill and only pay for resources when you really need them. In this blog I will auto scale Azure Spring Cloud with Azure Monitor and Azure Automation Runbooks in 4 steps. The methodology described here is a generic approach and will work with other Azure services as well. We will use the following components to build our automation and let’s cover some concepts first.

  • Azure Run As account: Azure automation account provides a container for your Azure Automation resources. When you create a Azure Run As account, it creates a new service principal in Azure Active Directory and assigns the Contributor role to this user at the subscription level. In our case, we will use the service principal created from the Azure Run As account to scale out apps.
  • Webhook: Webhook is a http callback endpoint. We will use it when an alert is triggered.
  • Alerts from Azure Monitor: Define alert conditions and actions based on resources consumed.
  • Performance testing from Application Insights: We will use performance testing from Application Insights to generate http load and trigger alerts.

In the automation flow, we will first generate http load from Application Insights. This will put pressure on our gateway service and increase App CPU consumption. Based on conditions defined, alerts will then be trigger and a webhook callback action is performance. The webhook will invoke an Azure Automation Runbook, which scales out our Spring Boot app.

 
 

flow.png

 

We’ll use Piggymetrics as our Spring Boot app. You can follow instructions here to create an Azure Spring Cloud instance and deploy Piggymetrics. Now let’s get started on building the automation.

Step 1 – create an automation account

From the Azure marketplace search for “automation”. Pick yes to create an Azure Run As account in the service creation step.

1.png    

Step 2 – create automation runbook

Once the automation account is created, head over to the process automation section of the automation account and click on runbooks. Create a runbook and pick PowerShell as the runbook type.

2.png

Copy and paste the code snippet in the PowerShell editor.

param

(

    [Parameter (Mandatory = $false)]

    [object] $WebhookData

)

 

   #connect to Azure using Azure Run As account

   Write-Output "Authenticating to Azure with service principal and certificate"

    $ConnectionAssetName = "AzureRunAsConnection"

    $servicePrincipalConnection = Get-AutomationConnection -Name $ConnectionAssetName       

    "Logging in to Azure..."

    Connect-AzAccount `

        -ServicePrincipal `

        -TenantId $servicePrincipalConnection.TenantId `

        -ApplicationId $servicePrincipalConnection.ApplicationId `

        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 

 

  

    if(-Not $WebhookData.RequestBody)

    {

        #allow test in test pane

        $WebhookData=(ConvertFrom-Json -InputObject $WebhookData)

        #convert webhook data to a Json object

        $WebhookData=(ConvertFrom-Json -InputObject $WebhookData.RequestBody)

    }

    else

    {

        #convert webhook data to a Json object

         $WebhookData=(ConvertFrom-Json -InputObject $WebhookData.RequestBody)

    }

 

    #retrieve alert data from webhook

    $AlertContext=$WebhookData.data.context

    #parse the name of the app that triggered the alert

    $AppName = $AlertContext.condition.allof.dimensions | where {$_.name -eq "AppName"}

    #appname is case sensitive as a part of the Azure resource ID. All my app names are lower case. In some cases Alert will 

    #capitalize the first letter of appname in the alert context. Make sure the case type matches with the name of your app.

    $AppName = $AppName.value.ToLower()

    $resourceId = ( $AlertContext.resourceId + '/apps/' + $AppName + '/deployments/default')

 

    #scale the app out by adding 1 more app instance

    $Resource = Get-AzResource -ResourceId $resourceId

    #retrieve current instance count and convert it to a number

    $IC = $Resource.Properties.deploymentSettings.instanceCount

    [int]$CurrentInstanceCount = [convert]::ToInt32($IC, 10)

    $TargetInstanceCount = $CurrentInstanceCount + 1

    Write-Output ( 'Scaling ' + $AppName.value + ' instance count from ' + $CurrentInstanceCount +' to ' + $TargetInstanceCount)  

    $Resource.Properties.deploymentSettings.instanceCount=$TargetInstanceCount

    $Resource | Set-AzResource -Force

    Write-Output 'Scaling completed'

 

 

Save and publish the runbook.

Lastly, we need to import dependencies for the PowerShell modules used in the code snippet. Go back to the automation account, under modules, click on browse gallery and import Az.Accounts and Az.Resources.

3.png

Step 3 – Add a webhook

From the overview menu of the runbook, click on Add webhook. An URL which includes a security token will be auto generated. Make sure you copy this URL and save it somewhere safe as it will not be available to you once the webhook is created.

Leave everything else as default in the parameters and run settings menu. Click on create to create the webhook.

4.png

Step 4 – Add an alert and connect it with the webhook

Add a new alert rule from Alerts under the Monitoring section of your Azure Spring Cloud service instance.

5.png

  1. Select “App CPU Usage Percentage (Platform)” under signal type.
  2. Select all services in the app dimension
  3. Set the alert to go off when average consumption is greater than 5%

6.png

Create a new action group for the alert condition. Pick webhook in the action type and paste the webhook callback URI that you save in step 3.

7.png

Step 4 – Test auto scale

To trigger the auto scale we will need to generate some load to get the average CPU consumption above 5%. I will use Azure Application Insights for this task. Create an Application Insights instance from the Azure portal and click on performance testing under the configure menu. Click on new and choose manual test under test type. Copy and paste the public endpoint of the piggymetrics gateway app and Click on run test.

8.png

 

After the load test is complete, let’s head back to Metrics under the Monitoring section of our Azure Spring Cloud instance. We see our average App CPU usage crept up to 10% during the load test.

9.png

Next we will check recent jobs under our automation account, and we see a new job has completed. Click on the job entry in the table to see details of this job.

10.png

You can find the input of the webhook data from the input tab. You can copy this data and use it as the input parameter when customizing the auto scale script.

11.png

The output tab shows output from the automation script, and you will see “Set-AzResource : The operation failed because resource could not be de-serialized.” Under the errors tab. You can ignore this message.

 

Finally, go back to your Azure Spring Cloud instance and verify that the gateway service has been scaled out to 2 instances.

12.png

Closing remarks

Congratulations, you’ve now set up auto scaling for you Azure Spring Cloud apps. Consider the following steps to take this setup for production.

  • Test and customize the automation script against your webhook, as your webhook input data may be different.
  • Figure out the right auto scale strategy based on your usage patterns, and the types of resources consumed by your apps.
  • Follow best practices for auto scale.
  • For advance load test scenarios you can use Gatling. It requires programing in Scala, but you can record test actions and replay them in scripts, once you configure Gatling as your local proxy in the browser.