Recently had a request to automate the shutdown (Stop) of VMs within and azure environment based on CPU usage. The scenario is there are high powered virtual machines that run workloads that can last anywhere from 3 – 14 hours, once these jobs are complete, the user returns and then shuts the virtual machine down at which point it gets deallocated. This can be quite costly especially if the jobs finish right before a weekend, thats at least 48 hours of a high spec VM running while not being used!

Using Azure Alerts on the VM and Web hooks in automation accounts, I was able to come up with a way to shut the virtual machines down and de-allocated when the CPU reached a certain threshold. 

This is how I achieved that:

Create an automation account if you don’t have one already; In the Automation account create a new runbook for shutting down virtual machines

 

I used the following runbook type – “Powershell”

Once the runbook is created, I used the following powershell code to actually do the dealloction and stop of the VM.

 

param(

  [Parameter(Mandatory)]$vmname,

  [Parameter(Mandatory)]$resourcegroup

)

$connectionName = "AzureRunAsConnection"

try

{

#Use the Azure Run As Connection defined above

$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

"Logging in to Azure..."

Add-AzureRmAccount  -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint

}

catch {

if (!$servicePrincipalConnection)

{

#Display any errors while logging in using Run As Account

$ErrorMessage = "Connection $connectionName not found."

throw $ErrorMessage

} else{

#Display any other errors

Write-Error -Message $_.Exception

throw $_.Exception

} }

# Required Modules - AzureRm.Profile and AzureRM.Insight. Define the Virtual machine being shutdown by this script.

$vm = Get-AzureRmVM -Name $vmname -ResourceGroupName $resourcegroup

try{

Stop-AzureRMvm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force

Write-Host "Shutdown of $($vm.Name) Successful"

}

catch

{

Write-Host "Error"

}

 

Click publish to save the runbook

 

Then click on Webhooks under the Resources section

 

Add a new webhook with the parameters of the VM Name and resource group of the VM

 

 

Once the web hook is created, go to the VM in the “VMNAME” parameter and click on the alerts option:

 

 

Add a new alert – Select the “Percentage CPU” metric and configure your thresholds, in this example, the machine will trigger an alert if the average CPU value for the past 5 minutes is less than 5%

Next, add a new action group and create an action of “Webhook”

 

Paste in the webhook URL from the webhook you created for the VM.

 

Once the action group is done, complete the alert config with a name and click ok to save the alert. Next time the alert triggers the VM will be stopped and deallocated.

 

Recently, I had to configure some storage accounts to consume Azure files for users. I decided to use private DNS servers and route all traffic down an existing Express route circuit.

 

The official documentation on configuring Private DNS and how it works can be found on the microsoft documentation site.

 

This article assume you already have a storage account setup with the appropriate container / file share already setup and these storage accounts are using private links.

 

To configure Private Link DNS – I did the following:

 

 Open up “Private DNS Zones” in the Azure portal

Once in Private DNS Zones, create a new zone and fill in the required details:

  • The name is the DNS name that will be applied to the storage account names. In a hub and spoke topology, deploy the new Zone in the hub subscription and network.

 

Once the Zone has been created, go to the required private links and select “DNS Configuration” then “+ Add Configuration”

 

Add the zone that was previously created

 

  • The configuration name is arbitrary, but it is recommended to use your storage account name or something that will help identify the resource

 

Once DNS zone configuration has been added – go back to the Private DNS zones and click on virtual network links

 

Then select Add, and add in the virtual network where your resources reside.

 

On your on-prem DNS servers you will need to create conditional forwarders for your cloud domains such as file.core.windows.net, blob.core.windows.net and any other ones you will be utilizing.  The conditional forwarders will need to point to an IaaS vm running DNS on it or any other DNS forwarder in the Azure environment. On the DNS forwarder in Azure you will need to point the same conditional forwarders to 168.63.129.16 (internal Azure DNS server)

If you get errors stating that the DNS forwarder is not authoritative for the domain, you can safely ignore these. 

 

Once this is complete you should be able to resolve internal addresses without having to change the resource.file.core.windows.net addressing on the front end. Hopefully, this will help on how to configure azure private dns with private links