How to automatically add your DevOps IP to Azure Analysis Services Firewall

Without adding the complete range of the datacentre

Since October 2017 it is possible to configure a firewall on your Azure Analysis Services. It is recommended to do this since it adds an extra layer of protection to your AAS. By default, AAS accepts all incoming network traffic from any client.

To be honest the firewall has very basic functionalities. Apart from on or off, there is a ‘Allow access from the Power BI Service’ button. Which I’m happy with is there, since it makes life a little bit easier. And there is functionality to add and delete IP-ranges. It does not have an option, like Azure SQL Server, to ‘allow all azure services’ (Basically, this adds all MS Azure Datacentres to a rule, not limited to your own subscription).

In this particular case, I’m using Azure DevOps for my repo and Azure Pipelines for a Continuous Integration and Delivery strategy. To manage the model, we have configured a couple of Logic Apps, in combination with the REST API, to Resume, Suspend, and Refresh the model.

So, enabling the Firewall on my AAS means that these clients are not able to do their work unless we add their IP address to the Firewall config. In this example, we will focus on Azure DevOps and how to allow traffic from the agent used in our CI/CD process.

The introduction article has some suggestions on how to overcome this problem. But also states, it is recommended to limit the number of rules to the absolutely necessary.

So how do we bring this back to just one rule?! Here is how we solved it.

PowerShell Script

The solution we implemented, involves a PowerShell script to set the firewall config. Apparently, more people run into the same challenge. We reused and altered the script a bit. The original is linked below.

Currently, it is not possible to alter or delete a single rule with the available PowerShell cmdlets. The only available commands are New-AzAnalysisServicesFirewallRule and New-AzAnalysisServicesFirewallConfig.

The script takes the currently applied firewall rules and the setting for the Power BI service. Stores these rules and updates the public IP address for the defined rule if needed and sets the firewall config on the Analysis Services.

#Author – Arthur Steijn // Motion10 // 20200708
#Original from Mathias Wrobel // Innofactor A/S
#Other sites to provide IPv4 public address with this type of request
<#
http://ipinfo.io/ip
http://ifconfig.me/ip
http://icanhazip.com
http://ident.me
http://smart-ip.net/myip
#>
# Set Parameters
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true)][String] $ResourceName = "AnalysisServicesName",
[Parameter(ValueFromPipeline = $true)][String] $ResourceGroup = "ResourceGroupName"
)
#Setting additional parameters
$ExistingFirewallRuleName = "AzureDevOps"
$PubIPSource = "ipinfo.io/ip"
$AServiceServer = Get-AzAnalysisServicesServer Name $ResourceName ResourceGroupName $ResourceGroup
$FirewallRules = ($AServiceServer).FirewallConfig.FirewallRules
$FirewallRuleNameList = $FirewallRules.FirewallRuleName
$powerBi = ($AServiceServer).FirewallConfig.EnablePowerBIService
#Getting previous IP from firewall rule, and new public IP
$PreviousRuleIndex = [Array]::IndexOf($FirewallRuleNameList, $ExistingFirewallRuleName)
$currentIP = (Invoke-WebRequest uri $PubIPSource UseBasicParsing).content.TrimEnd()
$previousIP = ($FirewallRules).RangeStart[$PreviousRuleIndex]
#Updating rules if request is coming from new IP address.
if (!($currentIP -eq $previousIP)) {
Write-Output "Updating Analysis Service firewall config"
$ruleNumberIndex = 1
$Rules = @() -as [System.Collections.Generic.List[Microsoft.Azure.Commands.AnalysisServices.Models.PsAzureAnalysisServicesFirewallRule]]
#Storing Analysis Service firewall rules
$FirewallRules | ForEach-Object {
$ruleNumberVar = "rule" + "$ruleNumberIndex"
#Exception of storage of firewall rule is made for the rule to be updated
if (!($_.FirewallRuleName -match "$ExistingFirewallRuleName")) {
$start = $_.RangeStart
$end = $_.RangeEnd
$tempRule = New-AzAnalysisServicesFirewallRule `
FirewallRuleName $_.FirewallRuleName `
RangeStart $start `
RangeEnd $end
Set-Variable Name "$ruleNumberVar" Value $tempRule
$Rules.Add((Get-Variable $ruleNumberVar ValueOnly))
$ruleNumberIndex = $ruleNumberIndex + 1
}
}
Write-Output $FirewallRules #Write all FireWall Rules to Host
#Add rule for new IP
$updatedRule = New-AzAnalysisServicesFirewallRule `
FirewallRuleName "$ExistingFirewallRuleName" `
RangeStart $currentIP `
RangeEnd $currentIP
$ruleNumberVar = "rule" + "$ruleNumberIndex"
Set-Variable Name "$ruleNumberVar" Value $updatedRule
$Rules.Add((Get-Variable $ruleNumberVar ValueOnly))
#Creating Firewall config object
if ($powerBi) {
$conf = New-AzAnalysisServicesFirewallConfig EnablePowerBiService FirewallRule $Rules
}
else {
$conf = New-AzAnalysisServicesFirewallConfig FirewallRule $Rules
}
#Setting firewall config
if ([String]::IsNullOrEmpty($AServiceServer.BackupBlobContainerUri)) {
$AServiceServer | Set-AzAnalysisServicesServer `
FirewallConfig $conf `
DisableBackup `
Sku $AServiceServer.Sku.Name.TrimEnd()
}
else {
$AServiceServer | Set-AzAnalysisServicesServer `
FirewallConfig $conf `
BackupBlobContainerUri $AServiceServer.BackupBlobContainerUri `
Sku $AServiceServer.Sku.Name.TrimEnd()
}
Write-Output "Updated firewall rule to include current IP: $currentIP"
Write-Output "Enable Power Bi Service was set to: $powerBi"
}

Azure Pipelines Task

We added an Azure PowerShell Task to the tasks of our deployment pipeline. This step is executed before the deployment of the model.bim. Make sure the service connection has the appropriate permissions on the AAS to perform the actions defined in the PowerShell script. You can find an example in yaml in here

steps:
task: AzurePowerShell@5
inputs:
azureSubscription: 'YourAzureSubscriptionOrServiceConnection'
ScriptType: 'FilePath'
ScriptPath: 'AddDevOpsIpToAAS.ps1'
ScriptArguments: '-ResourceName "YourAnalysisServicesName" -ResourceGroup "YourResourceGroupName"'
azurePowerShellVersion: 'LatestVersion'

Hopefully this article will make implementing the firewall a litte easier! And please let me know if you see any posible improvements!

References

Code examples

https://github.com/ArthurSteijn/AzureAnalysisServicesFirewallScripts

Introduction article Microsoft

https://azure.microsoft.com/nl-nl/blog/hardening-azure-analysis-services-with-the-new-firewall-capability/

More info on ‘Allow all Azure Services’: 

https://docs.microsoft.com/en-us/archive/blogs/azureedu/what-should-i-know-when-setting-up-my-azure-sql-database-paas

Azure Pipelines agents: 

https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=browser

Azure PowerShell issue: 

https://github.com/Azure/azure-powershell/issues/9566

PS script Mathias Wrobel: 

https://github.com/mathwro/Scripts/blob/master/Azure/AllowAzure-AnalysisServer.ps1

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 )

Connecting to %s

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close