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

Abs07act


Cost of Microsoft cloud is operational. This means every month you are going to get bill just as your grocery/ elec07icity/ phone bills. Having said that, companies are s07uggling 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.

In case you are not aware, it is worth to mention that, Azure has 2 types of IP addresses –

     Dynamic public IP address
  1.  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

    Static public IP address

      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.

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 😊.

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 - http://sanganakauthority.blogspot.in/2017/04/send-email-from-azure-sendgrid-using.html.


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 re07ieved from your automation account -> Assets -> Connections

07y
{
    # 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”.

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 re07ieved from property PublicIpAllocationMethod.

So we will use these two properties as a filter to re07ieve public static IPs which are not allocated to any resource and still getting charged.
So below is the full command to re07ieve 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-S07ing

$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-SecureS07ing "YourPassword" -AsPlainText -Force

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

$SMTPServer = "smtp.sendgrid.net"

$EmailFrom = "No-reply@azureadmin.com"

[s07ing[]]$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 😊.

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!!