Monday, May 20, 2019

D365FO / Azure Powershell NSG Rule Scripting to allow Azure Datacenters access


Currently we have the need to setup Azure based VM's for ISV products. Because of this we need to create NSG (Network security group)  rules to allow inbound and outbound communication so that D365FO can communication with these machines. However because the D365FO instances will not have a static IP we need to account for all of the Azure Data Center IP's so that we do not leave the public ip/port available for unwanted communication.

This is my first stab at Azure based powershell scripting. So I am not sure if this is optimal but it seems like there isn't much information out about D365FO communication with outside servers that are also hosted on Azure. So hopefully this will help others

The official list of Azure Data Center IP's can be found at the following locations:



In the following example we will open up Port 21 for inbound and outbound communication. It will detect to see if the NSG rule exists and if it does it will update the rule. If no rule is found then we will create the rule against the defined NSG.


You will need to gather the following data points in order for this to work.

Azure subscription id
Azure resource group that the network security group is associated with
Azure network security group name


All of the information can be found on either the overview page of the VM you are creating an NSG rule for or on the NSG itself.


It is good to note that currently NSG's have a limit of 1000 rules because of this we cannot define an rule per ip but rather must create a single rule that contains multiple ip ranges.




# Sign-in with Azure account credentials

Login-AzureRmAccount



# Select Azure Subscription

#Azure subscription id

$subscriptionId = '';

#Azure resource group name associated with the network security group

$rgName = '';

#Azure network security group that we need to create the rule against
$nsgname = '';









# Download current list of Azure Public IP ranges

Write-Host "Downloading AzureCloud Ip addresses..."

$downloadUri = "https://www.microsoft.com/en-us/download/confirmation.aspx?id=56519"

$downloadPage = Invoke-WebRequest -Uri $downloadUri;

$request = ($downloadPage.RawContent.Split('"') -like "*.json")[0];

$json = Invoke-WebRequest -Uri $request | ConvertFrom-Json | Select Values

$ipRanges = ($json.values | Where-Object {$_.Name -eq 'AzureCloud'}).properties.addressPrefixes



#set rule priority

$rulePriority = 200



    

#define the rule names    

$ruleNameOut = "Allow_AzureDataCenters_Out"

$ruleNameIn = "Allow_AzureDataCenters_In" 






#nonprod network security group 

$nsg = Get-AzureRmNetworkSecurityGroup -Name $nsgname -ResourceGroupName $rgName -ErrorAction:Stop;

Write-Host "Applying AzureCloud Ip addresses to non production NSG  $nsgname..."



#check to see if the inbound rule already existed

$inboundRule = ($nsg | Get-AzureRmNetworkSecurityRuleConfig -Name $ruleNameIn -ErrorAction SilentlyContinue)





if($inboundRule -eq $null)

{

    #create inbound rule    

    $nsg | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleNameIn -Description "Allow Inbound to Azure data centers" -Access Allow -Protocol * -Direction Inbound -Priority $rulePriority -SourceAddressPrefix $ipRanges -SourcePortRange * -DestinationAddressPrefix VirtualNetwork -DestinationPortRange 21   -ErrorAction:Stop | Set-AzureRmNetworkSecurityGroup -ErrorAction:Stop | Out-NULL;

     Write-Host "Created NSG rule $ruleNameIn for $nsgname"

}

else

{

    #update inbound rule

    $nsg | Set-AzureRmNetworkSecurityRuleConfig -Name $ruleNameIn -Description "Allow Inbound to Azure data centers" -Access Allow -Protocol * -Direction Inbound -Priority $rulePriority -SourceAddressPrefix $ipRanges -SourcePortRange * -DestinationAddressPrefix VirtualNetwork -DestinationPortRange 21 -ErrorAction:Stop | Set-AzureRmNetworkSecurityGroup -ErrorAction:Stop | Out-NULL;

    Write-Host "Updated NSG rule $ruleNameIn for $nsgname"

}



#check to see if the outbound rule already existed

$outboundRule = ($nsg | Get-AzureRmNetworkSecurityRuleConfig -Name $ruleNameOut -ErrorAction SilentlyContinue)



if($outboundRule -eq $null)

{

    #create outbound rule

    $nsg | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleNameOut -Description "Allow outbound to Azure data centers" -Access Allow -Protocol * -Direction Outbound -Priority $rulePriority -SourceAddressPrefix VirtualNetwork -SourcePortRange * -DestinationAddressPrefix $ipRanges -DestinationPortRange 21 -ErrorAction:Stop | Set-AzureRmNetworkSecurityGroup -ErrorAction:Stop | Out-NULL;

    Write-Host "Created NSG rule $ruleNameOut for $nsgname"

}

else

{

    #update outbound rule

    $nsg | Set-AzureRmNetworkSecurityRuleConfig -Name $ruleNameOut -Description "Allow outbound to Azure centers" -Access Allow -Protocol * -Direction Outbound -Priority $rulePriority -SourceAddressPrefix VirtualNetwork -SourcePortRange * -DestinationAddressPrefix $ipRanges -DestinationPortRange 21 -ErrorAction:Stop | Set-AzureRmNetworkSecurityGroup -ErrorAction:Stop | Out-NULL;

    Write-Host "Updated NSG rule $ruleNameOut for $nsgname"

}










 Write-Host "Finished."