Enable SQL Azure access from Azure WebJobs by adding firewall rules using PowerShell

Introduction

When we are developing custom Azure Web Apps or WebJobs, likely we will need access to Azure SQL database. Depends on the needs you will use Entity Framework, or direct Queries using Stored Procedures, but this is not the topic of this post. The topic today is how to allow our Azure WebJob to access to SQL Azure database, doesn’t matter what method we are using.

After some investigation, there are different ways to do that, I will share with you the different options I concluded:

The options

  1. Allow access other Azure Services image

    Security Note: this approach enables access to ALL AZURE SERVICES IN THE SAME REGION (even from other subscriptions).

  2. Allow Outbound IP Addresses of the Azure Web App in SQL Azure using a specific firewall rule

Read more…

Some useful references:

The approach and code

Now I will share the PowerShell script that you can configure with your Azure Web App and SQL Server details to add automatically the outbound IPs into SQL Azure firewall:

<#
.SYNOPSIS
Add SQL Server firewall rules using ARM (the rew Azure Resource Manager).
.DESCRIPTION
The JQ.Azure.WebJob.SQL.AddFirewallRules.ps1 function will iterate thru all Web App listed and add a new SQL Server rule for each Outbound Id Address
.PARAMETER Environment
All configuration will be set up on this file
.EXAMPLE
This exports the entire termstore.
./JQ.Azure.WebJob.SQL.AddFirewallRules.ps1
.NOTES
Requirements:
- Azure Powershell 1.0:
https://msdn.microsoft.com/library/mt619274.aspx
Download file: http://aka.ms/webpi-azps
How to install and configure Azure PowerShell: https://github.com/Azure/azure-content/blob/master/articles/powershell-install-configure.md
.AUTHOR
Jose Quinto: https://blog.josequinto.com
#>
####################################################
######## CONFIGURATION PARAMETERS #########
####################################################
# Azure Admin
$userName = "<user>@<tenant>.onmicrosoft.com"
$pass = "<password>"
# You can get it from https://manage.windowsazure.com --> Settings --> Subscriptions
$SubscriptionId = "<guid>"
# Web App Resource Group Name
$webAppRgName = "<web app resource group>";
# Web App Name
$webAppName = "<web app name>";
# SQL Server Resource Group Name
$sqlRgName = "<sql server resource group>";
# SQL Server Name
$sqlServerName = "<sql server name>";
# Define methods used for logging
Function LogSection ($message) {
Write-Host ""
Write-Host "** $($message) **" -ForegroundColor "magenta" #-BackgroundColor "blue"
}
Function LogWaiting ($message) {
Write-Host "$($message)... " -NoNewline -ForegroundColor "white" -BackgroundColor "blue"
}
Function LogInfo ($message) {
Write-Host $message #-ForegroundColor "white" -BackgroundColor "blue"
}
Function LogWarning ($message) {
Write-Host $message -ForegroundColor "yellow" #-BackgroundColor "blue"
}
Function LogError ($message) {
Write-Host $message -ForegroundColor "red" #-BackgroundColor "blue"
}
Function LogSuccess ($message) {
Write-Host $message -ForegroundColor "green" #-BackgroundColor "blue"
}
Function LogDuration ($startDate) {
$duration = (Get-Date) - $startDate
LogInfo "Script duration: $duration `n`n"
}
$cmdName = "Add-AzureRmAccount"
if (Get-Command $cmdName -errorAction SilentlyContinue)
{
try {
LogSection "Add SQL Firewall Rules from Web App outbound ips"
$startDate = (Get-Date)
LogInfo ("Script started: " + $startDate.ToString())
# Azure Authentication
LogWaiting "Authenticating on Azure"
$secureAdminPassword = $(convertto-securestring $pass -asplaintext -force)
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $secureAdminPassword
Add-AzureRmAccount -Credential $cred
LogSuccess "done"
LogDuration $startDate
# Setting Subscription Id
LogWaiting "Setting subscription Id ($SubscriptionId)"
Set-AzureRmContext -SubscriptionId $SubscriptionId
LogSuccess "done"
LogDuration $startDate
# Get Web App OutboundIpAddresses
LogWaiting "Get Web App OutboundIpAddresses"
$webapp = Get-AzureRmWebApp -ResourceGroupName $webAppRgName -Name $webAppName -errorAction SilentlyContinue
if ($webapp){
LogSuccess "$webAppName was found."
# Extract Outbound IPs
$ips = $webapp.OutboundIpAddresses
if ($ips){
$ipsArr = $ips -split ','
$ipsArr | ForEach {
$index = $ipsArr.IndexOf($_)
$ruleName = $webapp.SiteName + "-" + $index
$startIp = $_
$endIp = $_
Write-Host "Adding IP $index to SQL Server rule: $ruleName , StartIP: $startIp , EndIP $endIp"
$fr = Get-AzureRmSqlServerFirewallRule -ResourceGroupName $sqlRgName -ServerName $sqlServerName -FirewallRuleName $ruleName -errorAction SilentlyContinue
if ($fr){
# No changes on the IPs
if (($fr.StartIpAddress -eq $startIp) -and ($fr.EndIpAddress -eq $endIp)){
LogSuccess "$ruleName was already created and keep the same IPs ($startIp - $endIp)"
} else {
Set-AzureRmSqlServerFirewallRule -ResourceGroupName $sqlRgName -ServerName $sqlServerName -FirewallRuleName $ruleName -StartIpAddress $startIp -EndIpAddress $endIp
LogSuccess "$ruleName was already created but IPs has been updated to ($startIp - $endIp)"
}
}
else{
New-AzureRmSqlServerFirewallRule -ResourceGroupName $sqlRgName -ServerName $sqlServerName -FirewallRuleName $ruleName -StartIpAddress $startIp -EndIpAddress $endIp
LogSuccess "done"
}
}
}
else{
Write-Host "No Outbound IPs founded for $webAppName " -ForegroundColor Red
}
}
LogDuration $startDate
}
catch
{
Write-Host "Errors found:`n$_" -ForegroundColor Red
}
}
else{
LogError "$cmdName doesn't exists. Please install latest version of Azure Powershell 1.0: http://aka.ms/webpi-azps"
}

Important notes on the code:

  • Change all the configuration parameters including Azure Admin, Web App and SQL info.
  • Run the script and enjoy!

    Outbound Public URL aren’t Static by default, so probably they could change over the time (is not usual but can happen). So, I recommend some daily task to check every day and add the new IPs if needed. As the code is ready to update if the IPs are different. (read more here)

 

Author: José Quinto
Link: https://blog.josequinto.com/2016/09/19/enable-sql-azure-access-from-azure-webjobs-by-adding-firewall-rules-using-powershell/
Copyright Notice: All articles in this blog are licensed under CC BY-SA 4.0 unless stating additionally.