Automation Script to update firewall of Azure Analysis Services and WebApp

Welcome Forums General PowerShell Q&A Automation Script to update firewall of Azure Analysis Services and WebApp

This topic contains 5 replies, has 3 voices, and was last updated by

 
Participant
2 months, 3 weeks ago.

  • Author
    Posts
  • #162483

    Participant
    Topics: 2
    Replies: 4
    Points: 16
    Rank: Member

    Hi,

    I'm trying to create an Azure Automation job to request Azure IPs (only from "West Europe" and "North Europe") and update firewall rules on "Azure Analysis Services" (firewall) and "Web App" (Networking > Access Restrictions). The process needs to be done on Azure WebApp and Azure Analisys Services in the same script, at the same time.

    To do that manually I use this script:

    Azure Analysis Services

    Pre-requesits:

    #Run 2 functions to convert the CIDR address (and find the first and last IP of the network) to use in the next process
    
    Function Get-IPV4NetworkStartIP ($strNetwork)
    {
    $StrNetworkAddress = ($strNetwork.split("/"))[0]
    $NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes()
    [Array]::Reverse($NetworkIP)
    $NetworkIP = ([System.Net.IPAddress]($NetworkIP -join ".")).Address
    $StartIP = $NetworkIP +1
    #Convert To Double
    If (($StartIP.Gettype()).Name -ine "double")
    {
    $StartIP = [Convert]::ToDouble($StartIP)
    }
    $StartIP = [System.Net.IPAddress]$StartIP
    Return $StartIP
    }
    
    #Get-IPV4NetworkEndIP:
    
    Function Get-IPV4NetworkEndIP ($strNetwork)
    {
    $StrNetworkAddress = ($strNetwork.split("/"))[0]
    [int]$NetworkLength = ($strNetwork.split("/"))[1]
    $IPLength = 32-$NetworkLength
    $NumberOfIPs = ([System.Math]::Pow(2, $IPLength)) -1
    $NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes()
    [Array]::Reverse($NetworkIP)
    $NetworkIP = ([System.Net.IPAddress]($NetworkIP -join ".")).Address
    $EndIP = $NetworkIP + $NumberOfIPs
    If (($EndIP.Gettype()).Name -ine "double")
    {
    $EndIP = [Convert]::ToDouble($EndIP)
    }
    $EndIP = [System.Net.IPAddress]$EndIP
    Return $EndIP
    }
    
    #Variables
    
    #Analisys Services Service
    $aasRg = "sg-aasRg" #Name of Resource Group
    $aasName = "sg-aasName" #Name of "Azure Analysis Services" service
    
    $aasStartIp = "1.1.1.1" #First IP
    $aasEndIp = "1.1.1.2" #Last IP
    
    $aasFirewallRuleName = "Rule01" #Name of the rule (It's always necessary to increment the number of the rule manually...)
    
    #Update Analisys Services firewall
    
    #New rule configuration
    $NewRule1 = New-AzureRmAnalysisServicesFirewallRule -FirewallRuleName $aasFirewallRuleName -RangeStart $aasStartIp -RangeEnd $aasEndIp
    $FWConfig = New-AzureRmAnalysisServicesFirewallConfig -EnablePowerBIService -FirewallRule $NewRule1
    
    Set-AzureRmAnalysisServicesServer -Name $aasName -ResourceGroupName $aasRg -FirewallConfig $FWConfig
    

    (done...)

    Now, for the creation of rules to all Azure NE and WE IPs I need to execute the script:

    #Get all IPs of North Europe
    $allIPsNorthEU = (Get-MicrosoftAzureDatacenterIPRange -AzureRegion "north Europe").Subnet
    #Get all IPs of West Europe
    $allIPsWestEU = (Get-MicrosoftAzureDatacenterIPRange -AzureRegion "west Europe").Subnet
    
    $aasFirewallRuleName = 1 #I'm trying to use numbers but what I want to use is something like "Rule01,Rule02,...."
    $allIPs = (Get-MicrosoftAzureDatacenterIPRange -AzureRegion "north Europe").Subnet #I need to do that process to WE too.
    
    foreach ($IP in $allIPs)
    {
    if ($IP)
    {
    $aasFirewallRuleName++
    $Start = Get-IPV4NetworkStartIP $IP
    $End = Get-IPV4NetworkEndIP $IP
    
    Write-Host "Add IP Range to Firewall > $IP..."
    $a = New-AzureRmAnalysisServicesFirewallRule -FirewallRuleName $aasFirewallRuleName -RangeStart $Start -RangeEnd $End
    $FWConfig = New-AzureRmAnalysisServicesFirewallConfig -EnablePowerBIService -FirewallRule $a
    }
    }
    
    Set-AzureRmAnalysisServicesServer -Name $aasName -ResourceGroupName $aasRg -FirewallConfig $FWConfig
    

    But with this script only the last Rule/IPs are saved on the firewall configuration of Analisys Services Service 🙁

    Azure Web App
    For AzureWebApp I can use CIDR!

    My script is:

    #Azure WebApp
    
    #Variables
    
    $webappRg = "sg-webappRg"
    $AppServName = "sg-AppServName"
    
    function Add-AzureIpRestrictionRule
    {
    [CmdletBinding()]
    Param
    (
    # Name of the resource group that contains the App Service.
    [Parameter(Mandatory=$true, Position=0)]
    $ResourceGroupName,
    
    # Name of your Web or API App.
    [Parameter(Mandatory=$true, Position=1)]
    $AppServiceName,
    
    # rule to add.
    [Parameter(Mandatory=$true, Position=2)]
    [PSCustomObject]$rule
    )
    
    $ApiVersions = Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web |
    Select-Object -ExpandProperty ResourceTypes |
    Where-Object ResourceTypeName -eq 'sites' |
    Select-Object -ExpandProperty ApiVersions
    
    $LatestApiVersion = $ApiVersions[0]
    
    $WebAppConfig = Get-AzureRmResource -ResourceType 'Microsoft.Web/sites/config' -ResourceName $AppServiceName -ResourceGroupName $ResourceGroupName -ApiVersion $LatestApiVersion
    
    $WebAppConfig.Properties.ipSecurityRestrictions = $WebAppConfig.Properties.ipSecurityRestrictions + @($rule) |
    Group-Object name |
    ForEach-Object { $_.Group | Select-Object -Last 1 }
    
    Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion $LatestApiVersion -Force
    }
    
    $rule = [PSCustomObject]@{
    ipAddress = "191.235.209.0/20"
    action = "Allow"
    priority = 4 #I need to increment it manually...
    name = "Network 191.235.208.0/20 (NE)" #I need to increment it manually...
    description = "Range 191.235.208.0/20 of North Europe Datacenter" #When the CIDR is from North Europe
    }
    
    Add-AzureIpRestrictionRule -ResourceGroupName $webappRg -AppServiceName $AppServName -Rule $rule
    

    With this script I can add one Network at a time... and I need to add all the IP ranges of the 2 Azure Datacenters.

    The process needs to be done on Azure WebApp and Azure Analisys Services in the same script, at the same time 🙁

    And the big problem is that I don't know when these IPs changes!!

    For this reason (automate the process to import/update all the necessary IPs) I need to create a diary schedule... And I need your help to create this "Azure Automation".

    Another requirement that I have is the need to use Variables outside the Automation Script so it can be customizable on other scripts/services.

    Can you help me? Thanks for all your availability!

    Best regards

    Flot

  • #162498
    js

    Participant
    Topics: 25
    Replies: 677
    Points: 1,623
    Helping Hand
    Rank: Community Hero

    Someone else will probably answer this. But people are more likely to answer, if you could simplify your question.

  • #162507

    Participant
    Topics: 2
    Replies: 4
    Points: 16
    Rank: Member

    My main question is about the first point: "Now, for the creation of rules to all Azure NE and WE IPs I need to execute the script:".

    I don't know how can I make a process (loop) to import all the IPs on the same task to execute the "Add-AzureIpRestrictionRule" cmdlet.

    Can you help? Thanks for your help!

    Flot

  • #162528

    Participant
    Topics: 9
    Replies: 423
    Points: 675
    Helping Hand
    Rank: Major Contributor
    $allIPs = (Get-MicrosoftAzureDatacenterIPRange -AzureRegion "north Europe").Subnet 
    
    $i = 0 
    $FirewallRuleList = foreach ($IP in $allIPs) {
        $aasFirewallRuleName = "Rule$(([string]$i++).PadLeft(2,'0'))" # "Rule01,Rule02,...."
        $Start = Get-IPV4NetworkStartIP $IP
        $End   = Get-IPV4NetworkEndIP $IP
    
        Write-Host "Adding IP Range to Firewall > $IP..."
        New-AzureRmAnalysisServicesFirewallRule -FirewallRuleName $aasFirewallRuleName -RangeStart $Start -RangeEnd $End
    }
    $FWConfig = New-AzureRmAnalysisServicesFirewallConfig -EnablePowerBIService -FirewallRule $FirewallRuleList
    Set-AzureRmAnalysisServicesServer -Name $aasName -ResourceGroupName $aasRg -FirewallConfig $FWConfig
    

    The if statement is not required.
    To make rule names as Rule01, Rule02, ... use the PadLeft method of the String class as shown.
    As example 1 shows here, you need to build up the rule list (the $FirewallRuleList array in the code above) before you create the FW config

  • #162695

    Participant
    Topics: 2
    Replies: 4
    Points: 16
    Rank: Member

    The process doesn't work 🙁

    
    Set-AzureRmAnalysisServicesServer : The IP range System.Byte[]-System.Byte[] is invalid because the range start is greater than range end.
    At line:13 char:1
    + Set-AzureRmAnalysisServicesServer -Name $aasName -ResourceGroupName $ ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : CloseError: (:) [Set-AzAnalysisServicesServer], CloudException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.AnalysisServices.SetAzureAnalysisServicesServer
    
    

    Maybe I need to remove all the IPs first (or verify if it already exist) and add it after that.

  • #162698

    Participant
    Topics: 2
    Replies: 4
    Points: 16
    Rank: Member

    With the Sam Boutros tip (thanks!!!), now I have the second problem solved (creation of new IP rules on WebApp firewall)

    My solution:

    
    #Variables
    
    $webappRg = "rg"
    $AppServName = "app"
    
    function Add-AzureIpRestrictionRule
    {
    [CmdletBinding()]
    Param
    (
    # Name of the resource group that contains the App Service.
    [Parameter(Mandatory=$true, Position=0)]
    $ResourceGroupName,
    
    # Name of your Web or API App.
    [Parameter(Mandatory=$true, Position=1)]
    $AppServiceName,
    
    # rule to add.
    [Parameter(Mandatory=$true, Position=2)]
    [PSCustomObject]$rule
    )
    
    $ApiVersions = Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web |
    Select-Object -ExpandProperty ResourceTypes |
    Where-Object ResourceTypeName -eq 'sites' |
    Select-Object -ExpandProperty ApiVersions
    
    $LatestApiVersion = $ApiVersions[0]
    
    $WebAppConfig = Get-AzureRmResource -ResourceType 'Microsoft.Web/sites/config' -ResourceName $AppServiceName -ResourceGroupName $ResourceGroupName -ApiVersion $LatestApiVersion
    
    $WebAppConfig.Properties.ipSecurityRestrictions = $WebAppConfig.Properties.ipSecurityRestrictions + @($rule) |
    Group-Object name |
    ForEach-Object { $_.Group | Select-Object -Last 1 }
    
    Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion $LatestApiVersion -Force
    }
    
    $allIPs = (Get-MicrosoftAzureDatacenterIPRange -AzureRegion "north Europe").Subnet
    
    $i = 100
    $FirewallRuleList = foreach ($Range in $allIPs) {
    $rule = [PSCustomObject]@{
    ipAddress = $Range
    action = "Allow"
    priority = $(([string]$i++).PadLeft(2,'0')) # "101,102,...."
    name = "Network $Range (NE)"
    description = "Range $IP of North Europe Datacenter" #When the CIDR is from North Europe
    }
    Add-AzureIpRestrictionRule -ResourceGroupName $webappRg -AppServiceName $AppServName -Rule $rule
    }
    
    

    But It only have a problem, it's very slow (because it add one by one)!! Any idea how to perform it? Maybe this is an Azure service issue on Web App service...

    Unfortunately the problem with Azure Analysis Services persist... can anyone help, please?

    Thanks!

You must be logged in to reply to this topic.