Friday, August 11, 2017

How to receive an email on Azure Network Security Group Rule changes


Microsoft Azure Portal already gives a capability to receive an email alert when new Azure Network Security Group  (NSG) is added or existing is deleted. However there is no option today to receive an email when individual NSG security rules are added, deleted or modified. This post will provide the solution to receive emails on Azure NSG security rules changes which isn’t offered by Azure Portal.

Why do I need it?

If you are chief security officer of the company, then you definitely understand why do you care to receive an alert when NSG rules are changed.
NSG’s are fundamental to restrict/ allow access in Azure IaaS VM deployments. They offer controlled access using source and destination port, protocol and IP. So as a security best practice any Azure VM (Network Interface Card) NIC or Subnet in VNET should have NSG associated to it.
Having said that, maintaining rules in NSG is critical. Hence many times Azure portal administrators, CISO staff, IT head, Security head will always love to receive an email in Inbox to verify if the NSG security rule added/ modified/ deleted is after appropriate approval or no.

What do I need?

Creating alert is possible from Azure Monitor services. For example, if I want to create alert of NSG creation or deletion then below is the screenshot which shows how exactly you can configure alert.

As you can see in the above screenshot, there is no resource type available for NSG Security Rules. So, you may get under impression that “email alert on NSG security rule change can’t be configured”; which is wrong. The rule of thumb for Microsoft Azure I follow is
“If any functionality in not achievable from the Azure Portal then try it using Azure PowerShell or Azure ARM Templates.”
So, email alert on NSG security rule change can’t be configured from Portal however it is possible to configure using ARM Template.
Also, we need to create an “Action Group” on Azure portal so as to receive the email. So as a summary we will need below artifacts from Azure  -
1.      Azure ARM template to create Alert
2.      Action group to send emails
3.      Resource group which will contain the alert and action group.
So let’s get started.

Create Action Group

Creation an action group to send emails as per the steps mentioned in the link -
I have created an action group named as AdminsActionsGroup as shown below with Email as Action type –

After successful creation action group, you will receive an email about welcome as shown below –

Copy the resource ID for future use from overview tab as shown below –

Azure ARM Template to create NSG rule add/modify email alert

Out of the base ARM template present in above link, we need to replace the operationName for NSG rules Write operation as shown below –

Then search “templates” store at the top in Azure portal. Click on “add”, then provide the suitable name and description for the template. Copy the ARM template we created in above step. After adding the template it will be visible as below –

Complete template download is available at the end of this post.

Let’s deploy!

Click on the Deploy button as highlighted in above screenshot. Provide the action group resource id copied in above steps. Then click on “accept terms and condition” and then click on “Purchase” to complete deployment.

You can view the created alert as shown below –

Modify the security rule of any NSG present in Azure subscription and you should receive an email.

Email on Delete NSG Rule Operation

The approach is same. We need to create another alert for delete operation of NSG rules. Only the operation name will change as below –

Hope this helps.
Download complete script -

Backup NSG

I have seen many people asking about backing up NSG and rules. One way you can export the rules using PowerShell. 

If you want readymade solution then, to Backup NSG in your Azure Subscription I found one of the Marketplace solution. I have tried this at one of my customer and works good -

Tuesday, July 11, 2017

Start Stop Multiple Azure VMs on schedule using Azure Automation


I searched through many, many, many…articles written about Azure VM stop(de-allocate) to save cost. Every article only targets single Azure VM to shutdown (de-allocate). None of the articles target start and Shutdown of multiple Azure VMs using automation. I am going to address this using Azure powershell in this article.

What all Cool features of azure VM start/ stop my script offers?

If you have multiple Azure VMs present in your azure subscription; and you want to start or stop few of them on schedule then you can use below azure PowerShell scripts. It will have below features –
è  Add/ remove the VM names from the list of start/ stop schedule easily. [You don’t need to have PowerShell knowledge]
è  Use same script in multiple different Azure runbooks, with different Azure VM names to start and stop; that too with different schedules.
è  In case any wrong/ nonexistent VM name added to the list, script takes care of giving relative user-friendly message and do not throw error. It continues with other remaining set of Azure VMs and perform start or stop.
è  Can be used with single VM as well if required.
è  You start and stop azure VMs based on schedule hence obviously you optimize or save Azure cost.
è  Script is available for download; hence you can own it to change in future. [that’s cool 😊]
I can say all above feature are nothing but the “Key differentiator” or “Value Proposition” from other Azure VM shut down/ start automation blogs/ scripts. [These marketing terms; I hear them a lot 😊]

Fundamentals of Azure VM cost optimization

Azure VM are made of Compute and Storage. Compute is nothing but Core (number of cores/ CPUs) and RAM you get when you provision Azure VM. Storage is nothing but the C drive or other letter drives; except D drive for windows and Sdb drive for Linux]. These drives are nothing but disks or .vhd files present in Azure storage account [if VM is unmanaged] else disks or .vhd files will be part of your subscription [if VM is created using managed disks].
When we say you stop Azure VM from portal or using PowerShell command “Stop-AzureRMVm” basically Compute part of VM is released (or de-allocated). It is worth to mention here that “STORAGE PART REMAINS”.
So, when you think that if VM is in de-allocated state then I am not charged, YOU ARE WRONG. You are not charged for compute/Cores part; for storage capacity you are charged. However that is too cheap, so don’t worry. Cores are costly and that is where you save cost.
Also if you shutdown Azure VM after taking RDP/ SSH, compute is not released so you are charged for compute and storage both in that case. Therefore, it is recommended that you stop azure vm either using portal or PowerShell command. Refer the FAQ section from link for more details.
Let’s go back to script part now.

Stop multiple Azure VMs script

#define the VM names which are required to be shutdown
$vmNamesToBeShutDown = "vm1", "vm2", "vm3"

foreach($vmName in $vmNamesToBeShutDown)
    $resource = Find-AzureRmResource -ResourceNameEquals $vmName -ResourceType "Microsoft.Compute/virtualMachines"
    if($resource -ne $null)
        Write-Output "Stopping virtual machine..." + $vmName
        Stop-AzureRmVM -ResourceGroupName $resource.ResourceGroupName -Name $vmName -Force
        Write-output "Virtual machine not found:" + $vmName

The variable $vmNamesToBeShutDown is very important. This is where you can add as many VMs as you want to de-allocate them. The only requirement is to add VM name in double quotes and comma separated.
The code then traverse through each of the VM names, checks its existence and if found then fires command to de-allocate the azure vm.

Start multiple Azure VMs script

#define the VM names which are required to be shutdown
$vmNamesToBeStarted = "vm1","vm2", "vm3", "vm4"

foreach($vmName in $vmNamesToBeStarted)
    $resource = Find-AzureRmResource -ResourceNameEquals $vmName -ResourceType "Microsoft.Compute/virtualMachines"
    if($resource -ne $null)
        Write-Output "Starting virtual machine..." + $vmName
        Start-AzureRmVM -ResourceGroupName $resource.ResourceGroupName -Name $vmName
        Write-output "Virtual machine not found:" + $vmName

The structure of the start Azure VM script is same as that of Stop except the command used here to start VM is Start-AzureRmVM.
Here also you will only add VM names comma separated and they will get automatically started once you schedule script running.

Automate and schedule the start/stop Azure VM scripts

Azure automation allows you to create PowerShell script based runbook which can run automatically on pre-defined schedule.
The guidance here is copy paste above scripts in a runbook in PowerShell. When you plan to run the PowerShell as runbook make sure that you are using service principal authentication code at the start of runbook as depicted in this link – The authentication code should be added before any other PowerShell code in runbook. After creating runbook, publish it. Without publish runbook will not execute.
Then create schedule in automation account as per desired schedule. Screenshot below –

Once schedule is created, attach to runbook as below –

Similarly you can create as many as runbook and schedule them at your will and it should work.
Hope this helps.

Happy automating!!

You may be interested in – 

Domain join Azure virtual machine automatically using Azure Automation and DSC -

Friday, June 23, 2017

Azure VM SLA and high availability confusion


Since Microsoft Azure announced Single Instance SLA for Azure Virtual Machine, people are getting confused if availability sets with multiple VMs are required or no?
This post is to address various queries I received regarding Azure VM availability and SLA.
Disclaimer: All below views are personal. In no way, it represents the company I work for.

What is SLA?

SLA stands for Service Level agreement. It is a contract between service provider(here, Microsoft Azure) and end user(anyone, any organization who user Microsoft Azure services); that defines the level of service expected from the service provider.
If expected level of service is not provided and there is loss of business for end user then end user may claim for financial recovery with valid reasons, proofs, evidences etc. If evidences are valid and justified, then it will be an obligation for service provider to approve the claim and make payments.
Depending on the SLA provided, availability can be identified. Many online websites tools available for knowing what uptime of service you get based on SLA percentage. For example, if SLA offered as 99.90% means below can be approximate time periods of potential downtime/ unavailability of the service –
  • Daily: 1m 26.4s
  • Weekly: 10m 4.8s
  • Monthly: 43m 49.7s
  • Yearly: 8h 45m 57.0s
SLA percentage at 99.9% and above are general and industry accepted standards. Reference link used for calculation is here.

Recommendation for 99.95% availability for Azure VM – Availability sets

If you want to achieve 99.95% SLA for Azure VM deployment you should have at-least 2 instances of Azure VM running in Availability set.
P.S. Azure VMs with availability sets can be provisioned from the portal.
Irrespective of type of storage disk used for Azure VMs, SLA 99.95% is valid as long as you are running 2 instances in availability sets. This means if I want high availability for my crucial workloads under Azure VM then I should be running at least 2 VMs on azure in availability sets.
2 VMs with no availability sets means no SLA also. 😊

What is Azure VM - Single Instance SLA?

There were very important specific demand from customer –
-        “We want to run applications on azure that are not designed to run in multiple VMs. So how do we ensure reliability for such applications running on single Azure VM?”
-        “The application I am running on premises today is not designed for scale out. Also scale and management of the application is too expensive and cumbersome for me. What alternatives I have to move such a application to Azure immediately?”
The answer is Azure VM Single Instance SLA.
If you run single instance of Azure VM with premium disk or ultra you will get 99.9% SLA. 

Does Azure offer single instance SLA for Standard HDD and Standard SSD?

In July 2020, Microsoft Azure announced SLA of 99.5% for single instance Azure VMs using standard SSD and SLA of 95% for single instance Azure VMs using standard HDD disks. This improves availability offering for all types of single instance + disk combinations.

Does Single Instance SLA means High Availability?

No. A simple concept behind high availability is to have redundancy. With single instance there is no redundancy hence no high availability. But when I say no high availability does not mean that VM and applications hosted may face downtime anytime. Your VM will be up 99.9% time in its running lifetime. When Microsoft Azure plans to have maintenance, they will send you notification at-least 5 days before. So you can plan the downtime alternatives with applications running with single instance on Azure VM.
You want to go beyond 99.9% SLA, implement Availability sets and get 99.95% SLA. You want auto-scaling, go for VM Scale Sets. You want to go for 99.999 and so on availability; go for DR, backup strategy.


1.      Today Microsoft Azure is the only cloud who provides Single Instance SLA.
2.      Single instance SLA is guaranteed only when VM is running with all disks as Premium.
3.      Single instance SLA does not mean you get High availability for applications hosted in VM.
4.      To get High availability, run more than 1 VMs. [This doubles the cost, but there is a way to reduce the cost and still achieve HA; Of-course that is another blog on another day 😊].
5.      Most important – don’t commit to customer that “Single instance SLA means your application will never be down and it provides inbuilt HA”. 😐

Friday, May 19, 2017

Azure cost optimization – Send unassigned Azure public IP list using Azure PowerShell


Cost of Microsoft cloud is operational. This means every month you are going to get bill just as your grocery/ electricity/ phone bills. Having said that, companies are struggling these days to perform cost optimization or cost reduction on their Microsoft Azure spending.
Current article provides an Azure cost optimization tip by sending the list of unassigned public IPs present in your Azure subscription; as an email using Azure PowerShell and Azure Automation runbook.
Also I am talking about cost optimization (or cost reduction) for Public IP addresses related to Azure Resource Manager (ARM) mode.

Knowledge Update for you!!

In case you are not aware, it is worth to mention that, Azure has 2 types of IP addresses –
  1.  Dynamic public IP address
  2.  Static public IP address
IP addresses are always attached to Network Interface Card (NIC) of azure virtual machine. So their cost model is as below.

Dynamic public IP address

  1. IP address is attached to NIC of Azure VM, and VM is running, you are charged for approx. 197 INR/ month or 3$/ month.
  2. IP address is attached to NIC of Azure VM, and VM is in Stopped(De-allocated) state, you are not charged for dynamic public IP address.
Static public IP address

  1. Azure Static Public IP addresses are charged for reservation and usage both. This is double cost that of azure dynamic public IP cost.
  2. First 5 static public IP addresses cost for reservation is FREE. Only charged for usage at 197 INR/month or 3$/ month.
  3. All additional static public IP addresses are charged for Usage and Reservation both, as below -
a.      IP address is attached to NIC of Azure VM, and VM is running; you are charged for approx. 197 INR/ month or 3$/ month for reservation and 197 INR/ month or 3$/ month for usage. Total 394 INR/ month or 6$/ month.
b.      IP address is attached to NIC of Azure VM, and VM is in Stopped(De-allocated) state, you are charged for approx. 197 INR/ month or 3$/ month for reservation. There will be no usage charges.
c.       IP address is created in Azure subscription, not attached to any resource, still you are charged for approx. 197 INR/ month or 3$/ month for reservation. There will be no usage charges.

How we are going to save the azure operational cost?

From the above knowledge paragraph, it is evident that we need to be alert for Static Public IP cost only. As dynamic public IPs are not charged is not being used.
Hence we can optimize/ reduce/ save Azure billing “by deleting Azure Public static IP which is reserved but not attached/ associated to any resource”.
I am going to give you the Azure Automation PowerShell runbook for sending emails of such static unused but reserved public IP addresses.
Hope we are clear here 😊.

Create Sendgrid account on Azure to send emails

To send emails on Azure I always prefer sendgrid as it provide almost 25000 email/ month free. Get started with email account creation from here -

Create Azure Automation account and runbook

Below link specifies the steps to provision Azure Automation account – Create Azure Automation account.
After azure automation account creation, select option as Runbook -> Add a runbook -> Quick Create. Provide the name of runbook as “List-UnassignedPublicStaticIPs”. Runbook type as “PowerShell”. Provide meaningful description. Then click on Create.
Open newly created runbook and click on Edit option.
Now to run the PowerShell code in this runbook against our subscription, we need to provide authentication logic in the runbook first.  For the same add below code at the top of runbook –

$connectionName = "AzureRunAsConnection" #this should be your azure connection name. this can be retrieved from your automation account -> Assets -> Connections

    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName      
    "Logging in to Azure..."
    $account = Add-AzureRmAccount `
        -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
Write-Output $account

The above code segment ensures that your azure automation runbook don’t run into famous error “Run Login-AzureRmAccount for login”.

Retrieving unassigned static public IPs in Azure PowerShell

If azure public IP is not attached to any resource then its IpConfigurationText property is always null. Also, the public IP type is dynamic or static can be retrieved from property PublicIpAllocationMethod.
So we will use these two properties as a filter to retrieve public static IPs which are not allocated to any resource and still getting charged.
So below is the full command to retrieve azure public static un-assigned public IPs which can be delete to reduce monthly azure cost.

$unassignedIPs = Get-AzureRmPublicIpAddress | Where-Object IpConfigurationText -EQ null | where-object PublicIpAllocationMethod -EQ "Static" | ConvertTo-Html Name, IPAddress, ResourceGroupName,PublicIpAllocationMethod | Out-String

$unassignedIPs will contain the IP addresses. Now we need to send this is email. Therefore use below code of Sendgrid PowerShell to send email -
$Username ="YourUserName"

$Password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force

$credential = New-Object System.Management.Automation.PSCredential $Username, $Password

$SMTPServer = ""

$EmailFrom = ""

[string[]]$EmailTo = "YourEmail"

$Subject = "List of Un-assigned Public IPs"

$Body = $unassignedIPs + "Remember, every un-assigned Static IP is charged at the rate of <b>200 INR/Month</b>. So please delete it if not required."

Send-MailMessage -smtpServer $SMTPServer -Credential $credential -Usessl -Port 587 -from $EmailFrom -to $EmailTo -subject $Subject -Body $Body -BodyAsHtml
Write-Output "Email sent succesfully."

This code will send email all unassigned static public IPs.

Now run the “Test Pane” option of automation runbook and verify that you receive an email about un-assigned static public IP addresses present in your subscription. Then publish the runbook attach a schedule to it so that this runbook will execute automatically and you will receive email. Best frequency would be every Monday morning 9AM when office starts 😊.

Next Step

Obviously, delete the unassigned Azure public IPs from your subscription. You have the list received in your inbox; now delete it manually. Or if you are smart enough, you can use the command –  Remove-AzureRmPublicIpAddress

That’s all folks.
Happy Cost Optimization on Cloud!!

Saturday, May 6, 2017

Run Login-AzureRmAccount to login


Honestly, I did not know. This error has created so much of the frustration in the developers; who wishes to use Azure PowerShell and Azure Automation. This blog post is dedicated to solving the error “Run Login-AzureRmAccount to login”.


Any Azure RM [a.k.a Azure Resource Manager] PowerShell command execution first requires authentication done against your Azure subscription. So if you fire any command without Login-AzureRMAccount; above sweet error comes.

Reproducing the error

Let’s first reproduce this error.

I am assuming you already Azure PowerShell module installed. If not refer here for installation steps. Now open PowerShell and run the command to retrieve all Azure VMs present in the Azure subscription –


Error appears – “Run Login-AzureRmAccount to login”.

Solution is simple, run the command “Login-AzureRmAccount” and it opens up a pop up. Enter the credentials. After this run the command of retriving VMs again and everything works.

So, locally it’s easy to get rid of this error. How do we solve the error in Azure Automation account? Let’s first reproduce the same in Azure Automation account. I already have one Azure Automation account created as per the earlier blog post here. Refer section “Provision Azure Automation Account” in the blog post.

Click on Runbooks -> Add a Runbook. Give the name of your choice, select the type as “PowerShell”, and provide description of your choice. Then click on Create. After runbook is created on the Azure Portal, Open it by clicking on Edit option. Type the command as “Get-AzureRmVM”. Then to test the command click on “Test Pane” as highlighted below –

Click on Start button in Test Pane window to start the execution. There you receive the error again – “Run Login-AzureAccount to login”. Now here is the catch. Automation account runbooks runs in the background hence they can’t throw a pop up wherein you can put up your credentials. So how do we resolve it?

Solution is – Use Azure AD Service Principal

Service principal means you are treating an application as a user and giving full access to it so that it can perform any action against your azure subscription. As Azure subscription is always present in the Azure Active Directory tenant; we must add the information of our application in Azure AD tenant and this is nothing but the service principal.

So how do we create a Service principal? Well you don’t have to create because it already exists if you have an Azure ARM automation account created.

Open Assets -> Connections -> AzureRunAsConection. This shows type as Azure service principal and there are many Ids present as highlighted below –

Application Id is the one by which your Automation account is identified as Service principal in Azure AD. Tenant id is nothing but Azure AD id under which your subscription exists. Subscription Id is the actual Azure subscription Id.

Let’s verify this exist in your Azure AD as well. For the same, on Azure portal open Azure Active Directory -> App Registrations. You will see an Application Id same as what we have observed under automation account connection.

This means AzureRunAsConection of automation account is acting as Service principal. Hence it can be used for authentication against the subscription and also to perform operations against our azure subscription. With this let’s write some PowerShell code to perform authentication using service principal.

Authenticating using Service principal

Code for authenticating Azure Automation account runbook using Automation connection as Service principal is shown below –

$connectionName = "AzureRunAsConnection"
    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName      
    "Logging in to Azure..."
    $account = Add-AzureRmAccount `
        -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
Write-Output $account

Add above code segment in any runbook you wish to in Azure Automation account and you will never receive error of “Run Login-AzureRMAccount to login”.

I did the same in my sample runbook and VM list received. Below is the output –

That’s all folks.

Happy error handling!!