Azure VM’s unable to start via runbook

Whilst on customer site, issues began to arise with VM’s not starting in accordance with the shutdown/startup schedule, VM’s could take up to 4 hours to start. One of the customers requirements for this set of VM’s was that there was to be no internet access. After some investigation it was discovered that the reason for this delay was due to the extensions attached to the VM not being able to reach its corresponding Azure IP’s. Azure IP addresses currently within a vNet are classed as Internet addresses.

The resolution to this is the below PowerShell script. This will get all of the Azure IP address subnets Microsoft within a certain region and create NSG rules. You will need to change the value for the variable $nsgName.

# Sign-in with Azure account credentials

Login-AzureRmAccount

# Select Azure Subscription

$subscriptionId =
(Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription …” `
-PassThru).SubscriptionId

Select-AzureRmSubscription `
-SubscriptionId $subscriptionId

# Get Resource Group

$rsg =
$rgName = Get-AzureRmResourceGroup `
$rgName = $rgName.resourcegroupname |
Out-GridView `
-Title “Select an Azure RG …” `
-PassThru

# Download current list of Azure Public IP ranges
# See this link for latest list
$downloadUri = “https://www.microsoft.com/en-in/download/confirmation.aspx?id=41653”
$downloadPage = Invoke-WebRequest -Uri $downloadUri
$xmlFileUri = ($downloadPage.RawContent.Split(‘”‘) -like “https://*PublicIps*”)[0]
$response = Invoke-WebRequest -Uri $xmlFileUri

# Get list of regions & public IP ranges
[xml]$xmlResponse = [System.Text.Encoding]::UTF8.GetString($response.Content)
$regions = $xmlResponse.AzurePublicIpAddresses.Region

# Select Azure regions for which to define NSG rules
$selectedRegions = $regions.Name | Out-GridView -Title “Select Azure Datacenter Regions …” -PassThru
$ipRange = ( $regions | where-object Name -In $selectedRegions ).IpRange

# Put the rules in
$rules = @()
$rulePriority = 100
ForEach ($subnet in $ipRange.Subnet) {

$ruleName = “Allow_Azure_Out_” + $subnet.Replace(“/”,”-“)

$rules +=
New-AzureRmNetworkSecurityRuleConfig `
-Name $ruleName `
-Description “Allow outbound to Azure $subnet” `
-Access Allow `
-Protocol * `
-Direction Outbound `
-Priority $rulePriority `
-SourceAddressPrefix VirtualNetwork `
-SourcePortRange * `
-DestinationAddressPrefix “$subnet” `
-DestinationPortRange *

$rulePriority++

}

# Specify the NSG name that will have rules added to
$nsgName = “<NSG_Name>”

# Store NSG in variable
$nsg = Get-AzureRmNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName

# Foreach loop to add rules to NSG
foreach ($rule in $rules)
{
Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg `
-Name $rule.Name `
-Description $rule.Description `
-Access $rule.Access `
-Protocol $rule.Protocol `
-Direction $rule.Direction `
-Priority $rule.Priority `
-SourceAddressPrefix $rule.SourceAddressPrefix `
-SourcePortRange $rule.SourcePortRange `
-DestinationAddressPrefix $rule.DestinationAddressPrefix `
-DestinationPortRange $rule.DestinationPortRange
}

# Apply rules to the NSG.
Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $nsg -Verbose

Hopefully Microsoft will add a differentiation between Azure IP addresses and true Internet addresses. You can vote for this feature here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s