Azure DevOps: white list Azure Pipeline IP in Cosmos database firewall. How to add the Azure DevOps Hosted Agent IP address to a Cosmos database firewall.

I am currently doing the Azure backup strategy for one of our customers. While Azure takes regular backups of the Cosmos databases, in case of an application failure that would corrupt the data, they would not help. Because Azure would back up the already corrupted data.

The solution is to store our own backups. We use an Azure Pipeline which takes a daily backup of our databases.

But the problem is that the databases are IP restricted behind a firewall. And the Azure Pipeline fails because the Azure DevOps Hosted Agent cannot pass through the firewall.

The solution found is to add a step in our Azure Pipeline, which adds the Azure DevOps Agent IP address to the database white list and removes it at the end.

PowerShell script:

#Function to add current IP to database account
Function add-ip-databaseaccount ($customIP, $databaseResourceGroup, $databaseAccount){
    Write-Host "  " $customIP "is not allowed. Adding it now.." -ForegroundColor Green
    $databaseAccountIpRangeFilter = (Get-AzResource -Name $databaseAccount -ExpandProperties).Properties.ipRangeFilter
    $databaseAccountIpRangeFilter = $databaseAccountIpRangeFilter + "," + $customIP
    $databaseAccountProperties = @{"databaseAccountOfferType"="Standard"; "ipRangeFilter"=$databaseAccountIpRangeFilter}
    Set-AzResource -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ResourceGroupName $databaseResourceGroup -Name $databaseAccount -Properties $databaseAccountProperties -Force
    Get-AzResource -Name $databaseAccount -ExpandProperties
    #Although the IP is being added to the allowed list, it takes some time until the changes are being used
    Start-Sleep -Seconds 600
}

#Function to remove current IP to database account
Function remove-ip-databaseaccount ($customIP, $databaseResourceGroup, $databaseAccount){
    $databaseAccountIpRangeFilter = (Get-AzResource -Name $databaseAccount -ExpandProperties).Properties.ipRangeFilter
    $databaseAccountIpRangeFilter = $databaseAccountIpRangeFilter.Split(',')
    Write-Host Checking firewall settings for database $databaseAccount :
    if ($customIP -in $databaseAccountIpRangeFilter) {
        Write-Host "  " $customIP "is allowed. Removing it now.." -ForegroundColor Green
        [System.Collections.ArrayList]$ArrayList = [array]$databaseAccountIpRangeFilter
        $ArrayList.Remove($ArrayList[$ArrayList.IndexOf($customIP)])
        $databaseAccountIpRangeFilter = $ArrayList -join ','
        $databaseAccountProperties = @{"databaseAccountOfferType"="Standard"; "ipRangeFilter"=$databaseAccountIpRangeFilter}
        Set-AzResource -ResourceType "Microsoft.DocumentDb/databaseAccounts" -ResourceGroupName $databaseResourceGroup -Name $databaseAccount -Properties $databaseAccountProperties -Force
        Get-AzResource -Name $databaseAccount -ExpandProperties
    }
    else {
        Write-Host "  " $customIP "was already not allowed." -ForegroundColor Green
    }
}

#######################################################################

#Retrieve the current IP
$ipinfo = Invoke-RestMethod http://ipinfo.io/json
$myip = $ipinfo.ip

#Check if DB has IP filtering active:
$dbAccountIpRangeFilter = (Get-AzResource -Name $dbAccount -ExpandProperties).Properties.ipRangeFilter

#If IP filtering is in place
if($dbAccountIpRangeFilter)
{
    Write-Host "IP filtering is active for " $dbAccount
    $dbAccountIpRangeFilter = (Get-AzResource -Name $dbAccount -ExpandProperties).Properties.ipRangeFilter
    $dbAccountIpRangeFilterArray = $dbAccountIpRangeFilter.Split(',')
    Write-Host Checking firewall settings for db $dbAccount :

    if ($myip -in $dbAccountIpRangeFilterArray) {
        Write-Host "  " $myip "is already allowed." -ForegroundColor Green
        backup-db $dbResourceGroup $dbAccount $dbName $dbCollections
    }
    else{
        add-ip-dbaccount $myIp $dbResourceGroup $dbAccount
        backup-db $dbResourceGroup $dbAccount $dbName $dbCollections
        remove-ip-dbaccount $myIp $dbResourceGroup $dbAccount    
    }
}
else
{
    Write-Host "IP filtering is not active for " $dbAccount
    backup-db $dbResourceGroup $dbAccount $dbName $dbCollections
}

I will try to explain the function backup-database in a separate blog post.