Skip to main content

Azure Architecture - Solution Requirement Consideration Checklist

· 5 min read

Building a cloud solution on Azure can be an exciting yet daunting task.

The key to a successful implementation is carefully planning and considering solution requirements using the guidance of the Microsoft Cloud Adoption and Well Architecture frameworks.

But knowing what questions to ask and data to capture to give you the bigger picture - to not only consider the solution for the short term and long term, can be difficult. This is where the Azure architecture solution requirements checklist comes in.

Leaning on the great frameworks already in place to assist with the Cloud Adoption and Azure Well Architecture frameworks, the solution requirements checklist is intended to act as a way of asking and capturing the requirements of your solutions. It can be a great reminder to discover some of those requirements (whether functional or non-functional) that you may have forgotten about!

I am using the Azure Review Checklist - as a building block! I created a custom checklist intended to work alongside the review checklists - but aimed more at the discovery and requirements-gathering stage to assist with designing the proper outcomes for the business.

At the time of this article, there are 8 main categories, and various sub categories:

  • AI
  • Business
  • Data
  • Governance
  • Infrastructure
  • Microservices
  • Observability
  • Resiliency

Examples of some questions are:

Main AreaSub AreaChecklist itemDescription (optional)
BusinessGoalsWhy are we moving the solution to Azure?Understand the reasoning behind the decision to move to a cloud platform like Azure. Helps to validate the end result reaches this goal.
BusinessGoalsWhat are the business objectives or quantifiable business goals?What is the business objectives (ie Increased sales revenue, cost reduction, customer satisaction, employee productivity
BusinessGoalsWhat outcomes will you achieve for customer?What is the  objectives for the customer? What do they want to achieve using this solution
BusinessGoalsIs there a timeline for building the solution Azure?Asking about the timeline for building a solution in Azure is important to determine resource allocation, budgeting, prioritization, and setting stakeholder expectations.
BusinessGoalsHow many people will be accessing the solution?Asking about the number of people accessing the solution helps to determine the necessary resources and scalability required to accommodate the expected traffic and usage.
BusinessGoalsIs there a targeted event or date for an announcement about the solution's availability on Azure?Timeline for architecture, deployment, testing can help determine what risks, resource requirements and cost and the delivery of solution.
BusinessGoalsDoes the solution impact a Team, Department or organization?Impact on a team, department, or organization helps determine the scope and potential consequences of the solution, ensuring that all relevant stakeholders are considered and accounted for in the decision-making process.
BusinessCustomersWhat are the customer expecations?Customer expectations helps ensure that the solution meets the needs and desires of the end-users, and make sure business outcomes match customer expectations.
BusinessCustomersIs there a deal or customer opportunity associated with having the solution in Azure?Any associated deals or customer opportunities helps to understand the potential financial benefits, vendor offerings and growth opportunities of using Azure as a platform for the solution.

Azure Architecture - Solution requirement considerations

The Azure Architecture - Solution Requirement Consideration checklist, is intended to be a living resource, I am not an expert in all fields so there may be gaps or questions you feel is relevant or missing! Feel free to open a Pull Request to contribute! This is for you!

You can find the latest version of the checklist on GitHub here: lukemurraynz/Azure_Checklists

Using this is simple!

  1. Download the latest version of the excel spreadsheet from: Azure/review-checklists.
  2. Download the latest version of the Azure Architecture checklist.
  3. Open up the review_checklist excel document and click Import checklist from JSON
  4. Import checklist from file
  5. Import checklist from file
  6. Select the downloaded: azure_architecture_checklist.en.json

Once imported, you can now save the excel document, and start adjusting the Severity, Status and add Comments - to capture the information, to then use to architect your solutions!

Note: I do not create, edit or modify the Excel spreadsheet, created by for the Azure Reviews - I simply use it to run my custom checklist. Make sure to check out the Azure Review Checklists!

There are some settings that you might need to change in your system to run macro-enabled Excel spreadsheets. When initially opening the file you may see the following error, which prevents Excel from loading:

Excel cannot open the file 'review_checklist.xlsm' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

In other cases the file opens with the following message, which prevents you from being able to load the checklist items:

Unblock file or add an exception to Windows Security

  1. You might need to unblock the file from the file properties in the Windows File Explorer, so that you can use the macros required to import the checklist content from github.com:
  2. Additionally, you might want to add the folder where you cloned this repo to the list of exceptions in Windows Security (in the Virus & Threat Protection section):

Azure Deployment history cleanup with Azure DevOps

· 7 min read

Microsoft Azure has a limit of 800 deployments per resource group. This means that a single resource group can only contain 800 historical deployments at most.

A deployment in Azure refers to the process of creating or updating resources in a resource group.

When deploying resources in Azure, it is essential to keep track of the number of historic deployments in a resource group to ensure that the limit is not exceeded. This is because new deployments will fail if the limit is exceeded, and creating or updating resources in that resource group will not be possible.

If you have CI/CD (Continuous Integration and Continuous Deployment) set up to deploy or change your infrastructure or services with code, it can be easy to reach this limit. Azure will attempt to do this automatically when reaching your limit. Still, you may want to pre-empt any problems if you make many deployments and the system hasn't had time to prune automatically, or this is disabed.

This came up in conversations on Microsoft Q&A, so I thought I would dig into it and put together a possible option.

To avoid exceeding the deployment limit, it may be necessary to clean up old deployments.

This can be done by using a script to remove deployments that are no longer needed.

So let's build an Azure DevOps pipeline that runs weekly to connect to our Microsoft Azure environment and clean up historical deployments.

Microsoft Azure Deployment History Cleanup with Azure DevOps

For this article, I will assume you have an Azure DevOps repository setup and the permissions (Owner) to make the necessary privileged actions to the Microsoft Azure environment to do the design.

Note: Scripts and pipeline are "here".

Deploy and Configure

Create Service Prinicipal
  1. Navigate to the Microsoft Azure Portal
  2. Click on Microsoft Entra ID
  3. Click on App Registrations
  4. Click on: + New Registration
  5. Enter the following information:
    • Name (i.e. SPN.AzDeploymentCleanup)
  6. Click Register
  7. Copy the following for later when we add the SPN to Azure DevOps.
    • Application (client) ID
    • Directory (tenant ID)
  8. Click on Certificates & Secrets
  9. Press + New Client Secret
  10. Enter a relevant description and expiry date and click Add
  11. Copy the value of the new secret (this is essentially your password), and you won't be able to see the matter again.
Create Custom Role & Assign permissions

Now that your service principal has been created, it is time to assign permissions because this script targets all subscriptions under a management group; we are going to set the permissions to that management group so that it flows to all subscriptions underneath it - and in the view of least privileged we will create a Custom Role to apply to our Service Principal.

Create Custom Role

For the deployment history to be completed, we will need the following permissions:

  • Microsoft.Resources/deployments/delete
  • Microsoft.Resources/subscriptions/resourceGroups/read
  • Microsoft.Management/managementGroups/read
  • Microsoft.Resources/subscriptions/read
  • Microsoft.Management/managementGroups/descendants/read
  • Microsoft.Management/managementGroups/subscriptions/read
  • Microsoft.Resources/subscriptions/resourcegroups/deployments/operations/read
  • Microsoft.Resources/subscriptions/resourcegroups/deployments/read
  • Microsoft.Resources/subscriptions/resourcegroups/deployments/write
  • Microsoft.Resources/deployments/read
  1. Navigate to the Microsoft Azure Portal
  2. In the search bar above, type in and navigate to Management Groups
  3. Click a management group, click on Access Control (IAM)
  4. Click + Add
  5. Click Add Custom Role
  6. Type in a role name (an example is: AzDeploymentHistoryCleanup)
  7. Check Start from Scratch and next click
  8. Click + Add permissions and the permissions above (you can search for them). Feel free to import the role from a JSON file "here".
  9. Click Next
  10. Add Assignable Scopes (this is the scope you can use to assign a role to - this won't give it to the Service Principal; it will only open it up so we can post it). Make sure you set it at the management group level you are targetting.
  11. Click Review + Create
  12. Click Create
Assign Permissions

Now that the custom role has been created, it is time to assign it to the service principal we made earlier.

  1. Navigate to the Microsoft Azure Portal
  2. In the search bar above, type in and navigate to Management Groups
  3. Click on the management group you want to manage and click on Access Control (IAM)
  4. Click Add
  5. Click Add Role Assignment
  6. Select your custom role (you can toggle the type column, so CustomRoles are first in the list)
  7. Microsoft Azure - add role assignments
  8. Click Members
  9. Make sure 'User, group or service principal' is selected and click + Select Members
  10. Microsoft Azure - Add Roles.
  11. Select your Service Principal created earlier (i.e. SPN.AzDeploymentCleanup)
  12. Click Select
  13. Click Review + assign to assign the role.

Note: Copy the Management Group ID and name, as we will need the information, along with the Service Principal and tenant IDs from earlier, in the next step of setting up Azure DevOps.

Configure Azure DevOps Service Endpoint

Now that the Service Principal and permissions have been assigned in Azure, it's time to create the service connection endpoint that will allow Azure DevOps to connect to Azure.

  1. Navigate to your Azure DevOps organisation.
  2. Create a Project, if you haven't already
  3. Click on Project Settings
  4. Navigate to Service Connection
  5. Click on New service connection
  6. Select Azure Resource Manager
  7. Click Next
  8. Select Service principal (manual)
  9. Click Next
  10. For the scope, choose Group Management
  11. Enter the Management Group ID, the Management Group Name
  12. Time to enter in the Service Principal details copied earlier, for the Service Principal Id paste in the Application ID.
  13. The Service Principal key, enter the secret client value and select the Tenant ID
  14. Click Verify - to verify the connectivity to the azure platform from Azure DevOps
  15. Select Grant access permission to all pipelines and click Verify and save
Configure script and pipeline

Now that we have our:

  • Azure Service Principal
  • Custom role and assignment
  • Service connection

We now need to import the script and pipeline.

If you haven't already done - create a Repo for the AzHistoryCleanup writing.

You can clone (or copy) the files in the AzDeploymentCleanup Repo to your own.

First, we need to copy the name of the Service Principal.

  1. Click Project settings
  2. Click Service Connections
  3. Click on your Service Connection and copy the name (i.e. SC.AzDeploymentCleanup)
  4. Azure DevOps Service Principal
  5. Navigate back to your Repo, and click on AzDeploymentCleanup.yml (this will become your pipeline)
  6. Click Edit
  7. Edit AzDeploymentCleanup YML
  8. Update the variable for ConnectedServiceNameARM to the name of your service connection
  9. Here you can also edit the Script Arguments - for example, in my demo, I am targeting the ManagementGroup named: mg-landing zones and keeping the latest five deployments.
  10. By default, I also have a cron job to schedule this pipeline at 6 AM UTC every Sunday, and you can remove or edit this.
  11. Once your changes are made, click Commit.
  12. Now that your pipeline has been updated, its time to create it - click on Pipelines.
  13. Click New Pipeline
  14. Select Azure Repos Git (YAML)
  15. Select your Repo
  16. Select Azure DevOps repo
  17. Select Existing Azure Pipelines YAML file
  18. Select YAML
  19. Select your Pipeline YAML file and click Continue
  20. Click Save to create the pipeline
  21. Now it's time to run the pipeline! Click Run pipeline
  22. Azure DevOps - Pipeline run
  23. If successful, your script will trigger and clean up the oldest deployment history! This can take several minutes to run if you have a lot of deployments.

Azure Deployments - Cleanup - Comparison 1

Azure Deployments - Cleanup - Comparison 2

You Can't Touch This: How to Make Your Azure Backup Immutable and Secure

· 5 min read

With immutable vaults, Azure Backup ensures that recovery points that are once created cannot be deleted before their intended expiry time. Azure Backup does this by preventing any operations which could lead to the loss of backup data.

Hence, this helps you protect your backups against ransomware attacks and malicious actors by disallowing operations such as deleting backups or reducing retention in backup policies.

Immutable vaults is now Generally available in all regions (March 13th 2023).

An immutable vault can assist in safeguarding your backup data by prohibiting any actions that might result in the loss of recovery points.

Can't touch this

By securing the immutable vault setting, it can be made irreversible, which can prevent any unauthorized individuals from disabling the immutability feature and erasing the backups.

The Immutable vault configuration supports both Recovery Services vaults and Backup vaults.

While Azure Backup stores data in isolation from production workloads, it allows performing management operations to help you manage your backups, including those operations that allow you to delete recovery points. However, in certain scenarios, you may want to make the backup data immutable by preventing any such operations that, if used by malicious actors, could lead to the loss of backups. The Immutable vault setting on your vault enables you to block such operations to ensure that your backup data is protected, even if any malicious actors try to delete them to affect the recoverability of data.

Enabling immutability for the vault is a reversible operation. However, you can make it irreversible to prevent any malicious actors from disabling it (after disabling it, they can perform destructive functions).

The type of operations enabling immutability on the Azure Backup vault can prevent and safeguard from is.

SystemOperation typeDescription
Recovery Services Vault & Backup VaultStop protection with delete dataA protected item can't have its recovery points deleted before their respective expiry date. However, you can still stop protection of the instances while retaining data forever or until their expiry.
Recovery Services VaultModify backup policy to reduce retentionAny actions that reduce the retention period in a backup policy are disallowed on Immutable vault. However, you can make policy changes that result in the increase of retention. You can also make changes to the schedule of a backup policy.
Recovery Services VaultChange backup policy to reduce retentionAny attempt to replace a backup policy associated with a backup item with another policy with retention lower than the existing one is blocked. However, you can replace a policy with the one that has higher retention.

There are three current states for the immutability of the Backup and Recovery Services Vault:

  • Disabled
  • Enabled (soft immutability)
  • Enabled and locked (hard immutability)
State of Immutable vault settingDescription
DisabledThe vault doesn't have immutability enabled and no operations are blocked.
EnabledThe vault has immutability enabled and doesn't allow operations that could result in loss of backups. However, the setting can be disabled.
Enabled and lockedThe vault has immutability enabled and doesn't allow operations that could result in loss of backups. As the Immutable vault setting is now locked, it can't be disabled. Note that immutability locking is irreversible, so ensure that you take a well-informed decision when opting to lock.

Immutable vaults and multi-user authorization can safeguard your backups from various human and technological accidents or disruptions.

Immutable vaults will not affect live or hot backups, such as snapshots.

Using the Azure Portal, let us configure immutability on your Azure Backup Vault.

  1. Navigate to your Recovery Services Vault
  2. Navigate to Properties (under Settings)
  3. Recovery Services Vault - Immutability
  4. Under Immutable vault, select Settings
  5. Click the box to enable vault immutability
  6. Enable vault immutability
  7. Click Apply
  8. The Recovery Services vault will be adjusted, and the status has changed to Enabled but not locked; this means that your vault is now immutable and won't allow operations that will result in the loss of backups; however, you can reverse the change by unticking vault immutability.
  9. Immutable vault - soft
  10. To hard lock, your vault, navigate back into the Immutable vault settings, toggle Locked, and Apply. This cannot be undone, so make this decision thought out, as it will stop the ability to reduce retention policies that will cause the deletion of recovery points, which could lead to increased costs in the longer term.

The Azure Backup vault immutability can also be adjusted using Azure Bicep, reference below.

param vaults_name string = 'rsv'

resource vaults_name_resource 'Microsoft.RecoveryServices/vaults@2022-09-10' = {
name: vaults_rsv_name
location: 'australiaeast'
sku: {
name: 'RS0'
tier: 'Standard'
}
properties: {
securitySettings: {
immutabilitySettings: {
state: 'Unlocked'
}
}
}
}

The immutabilitySettings states are:

StateActions
DisabledImmutability is Disabled
LockedEnabled but locked
UnlockedEnabled but unlocked

Note: I was able to delete a Recovery Vault, with locked Immutability successfully, that didn't have any Recovery points.

Export icons to SVG from the Microsoft Azure Portal using Amazing Icon Downloader

· 2 min read

Have you ever wanted to export an icon from the Microsoft Azure Portal but found yourself having to screenshot the icon at a low definition to include in your documentation or presentations?

Well - using the Amazing Icon Downloader browser plugin, you can export a single or all icons on a specific page in high definition as an SVG (Scalable Vector Graphics) file.

Easily view all icons on a page, works with:

  • portal.azure.com
  • endpoint.microsoft.com
  • Search to filter down long lists of icons
  • Rename and download any single icon
  • Bulk download all icons as a .zip file
  • Works with either Chrome or Edge

The plugin is available on Chrome or Edge browser stores and is intuitive.

Once you install it, it is a matter of browsing the page you want and clicking the extension to export.

Azure Icon Downloader

If you are after Visio stencils and other files, make sure you also check out David Summers Azure Stencil collection.

You may run into an issue where a new feature or icon is released, and the stencil collection hasn't been updated yet - which is where the Amazing Icon Downloader can come in handy.

Create Azure IP Groups based on the IP address ranges of countries

· 9 min read

An IP Group in Microsoft Azure is a logical container of IP address ranges for private and public addresses.

IP Groups allow you to group and manage IP addresses for Azure Firewall rules in the following ways:

  • As a source address in DNAT rules
  • As a source or destination address in network rules
  • As a source address in application rules

An IP Group can have a single IP address, multiple IP addresses, one or more IP address ranges or addresses and ranges in combination.

The IP Group allows you to define an IP address that can be used in conjunction with Azure Firewall, to allow or deny internal or external traffic from a perspective set of IP addresses.

The following IPv4 address format examples are valid to use in IP Groups:

  • Single address: 10.0.0.0
  • CIDR notation: 10.1.0.0/32
  • Address range: 10.2.0.0-10.2.0.31

By default, the Azure Firewall blocks outbound and inbound traffic; however, you may want to enable (or block) traffic to and from specific countries - there is no built-in geo-filtering with Azure Firewall, as you can use other services, such as the Web Application Gateway and with the Application Gateway and Azure Front Door to block and allow access, and other third party services such as Cloudflare. This script can be adapted for any list of IP ranges; it doesn't need to be country IP addresses.

However, you may want to control access to and from specific countries (or other services) with Azure Firewall - this is where the IP Groups can be effective, and because we won't be editing the Firewall directly - we won't run into issues with delays without having to wait for the Azure Firewall policies to be updated.

To solve the issue of creating the IP groups and finding and keeping the IP groups up-to-date with various countries' IP ranges - I have created a PowerShell function to retrieve supported countries' IP CIDR ranges and create the relevant IP groups.

Azure IP Group - Country IP ranges

With IP Groups, there are a few things to keep in mind:

  • You can have 200 IP Groups per firewall with a maximum of 5000 individual IP addresses or prefixes per each IP Group.

For a country like New Zealand, the 5000 limit for the address ranges is acceptable - but for other countries, like the United States or United Kingdom, this can be an issue, where the total IP ranges can grow to over 20k - to deal with this, the script will create multiple IP Groups, and append a number to the end.

Suppose IPs are manually added to the groups. In that case, they won't be added - the script will add in any different or new IP ranges, ignoring any current IP ranges (this means it won't delete any IP ranges that are removed from the source IP list from IPDeny); however, I recommend that anything added outside of this script is kept in a separate IP group.

As with any script, I recommend this is tested in a test environment first.

Before we run it, we need a few prerequisites.

The function assumes you have connected to Microsoft Azure and your relevant subscription.

Before we import the function, I am going to check if any IP groups already exist quickly (this isn't required) - but it's a good opportunity to check that you are connected to your Azure subscription and that the AzIPGroup cmdlets exist - and whether you have any IP groups already existing.

Get-AzIpGroup

Get-AzIpGroup

I have received no errors or existing IP groups in my subscription, so I will continue importing my function.

The function can be found here:

New-AzCountryIPGroup.p1
function New-AzCountryIPGroup {
<#
.SYNOPSIS
Creates an Azure IP group, with the IP address ranges for various countrues.
The code does the following:
1. It downloads the IP address ranges for the country specified.
2. It checks if the IP Group already exists, if it does, it adds the IP addresses to the existing IP Group.
3. If the total number of IP addresses is less than 5000, it will add the IP addresses to the existing IP Group.
4. If the total number of IP addresses is over 5000, it will create a new IP Group, with the same name as the existing IP Group, and it will add the IP addresses to the new IP Group.
5. If the new IP Group is over 5000, it will create a new IP Group, with the same name as the existing IP Group, and it will add the IP addresses to the new IP Group.
6. It will continue to create new IP Groups until all of the IP addresses are added.

The code can be used to create IP Groups for multiple countries, and if the number of IP addresses is over 5000, it will create multiple IP Groups, with the same name, but with a counter after the name, so that it will be unique.
.EXAMPLE
New-AzCountryIPGroup
New-AzCountryIPGroup -CountryCode NZ -IPGroupName IP -IPGroupRGName NetworkRG -IPGroupLocation AustraliaEast
.AUTHOR
Luke Murray - https://luke.geek.nz/

#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, Position = 0)]
[System.String]
$CountryCode,
[Parameter(Mandatory = $true, Position = 1)]
[Object]
$IPGroupName,
[Parameter(Mandatory = $true, Position = 2)]
[System.String]
$IPGroupRGName,
[Parameter(Mandatory = $true, Position = 3)]
[System.String]
$IPGroupLocation
)


$IPBlocks = Invoke-WebRequest -Uri ('https://www.ipdeny.com/ipblocks/data/aggregated/{0}-aggregated.zone' -f $CountryCode.ToLower())
#Exports the IPBlock content from the HTML request, into a String
$IPBlock = $IPBlocks.Content
#Spilts each IP block, into a seperate object
$ipaddressranges = $IPBlock -split '\s+' -replace '\r?\n\r?', '' | Where-Object { $_ -ne '' }

$Group = Get-AzIpGroup -Name $IPGroupName -ResourceGroupName $IPGroupRGName

if ($ipaddressranges.Length -lt 5000) {

If ($null -eq $Group) {
Write-Host "Group doesn't exist, creating a new IP Group called $IPGroupName in the following Azure Resource Group $IPGroupRGName and location $IPGroupLocation"
$Group = New-AzIpGroup -Name $IPGroupName -ResourceGroupName $IPGroupRGName -Location $IPGroupLocation -Tag @{Country = $CountryCode } -Verbose

If ($null -eq $Group) {
New-AzResourceGroup -Name $IPGroupRGName -Location $IPGroupLocation -Tag @{Country = $CountryCode }
$Group = New-AzIpGroup -Name $IPGroupName -ResourceGroupName $IPGroupRGName -Location $IPGroupLocation -Tag @{Country = $CountryCode } -Verbose

}

ForEach ($ip in $ipaddressranges) {
$Group.IpAddresses.Add($ip)
Write-Host "Adding $ip to $IPGroupName."
}

$Group | Set-AzIPGroup -Verbose

}

else {
Write-Host "Group already exists called:$IPGroupName in the following Azure Resource Group $IPGroupRGName and location $IPGroupLocation. Adding IPs to the group... Please note that this script doesn't check already existing IP addresses, if identical IP addresses exist, it will overrite it, if IP addresses outside of the Country List exist, it will remain in the IP Group - but there is no checking, if there is pre-equisting IP addresses in the IP Group that will raise the Group Limit above 5000. I recommend keeping the Country IP group seperate."
$Group = Get-AzIpGroup -Name $IPGroupName -ResourceGroupName $IPGroupRGName


ForEach ($ip in $ipaddressranges) {
$Group.IpAddresses.Add($ip)
Write-Host "Adding $ip to $IPGroupName"
}

$Group | Set-AzIPGroup -Verbose
}
}

else {

Write-Host "Azure IP Groups only support IPAddresses of up-to 5000 (the country you have specified is: "$ipaddressranges.Length"), also please make sure the country code matches https://www.ipdeny.com/ipblocks/data/aggregated/"

$counter = [pscustomobject] @{ Value = 0 }
$groupSize = 5000
$groups = $ipaddressranges | Group-Object -Property { [math]::Floor($counter.Value++ / $groupSize) }
$counter = 0
ForEach ($group in $groups) {
$countup = $counter + 1

$azipgroup = Get-AzIpGroup -Name "$IPGroupName$countup" -ResourceGroupName $IPGroupRGName -Verbose


If ($null -eq $azipgroup) {
$countup = $counter + 1
Write-Host "$IPGroupName$countup doesn't exist. Creating... $IPGroupName$countup in the following Resource Group $IPGroupRGName and location $IPGroupLocation."
$azipgroup = New-AzIpGroup -Name "$IPGroupName$countup" -ResourceGroupName $IPGroupRGName -Location $IPGroupLocation -Tag @{Country = $CountryCode } -Verbose -Force
$ipgroup = $group.Group
ForEach ($IP in $ipgroup) {
$azipgroup.IpAddresses.Add($IP)
Write-Host "Adding $ip to $IPGroupName"
}

$azipgroup | Set-AzIPGroup -Verbose
$counter++

}
else {
$ipgroup = $group.Group
ForEach ($IP in $ipgroup) {
$azipgroup.IpAddresses.Add($IP)
Write-Host "Adding $ip to $IPGroupName"
}

$azipgroup | Set-AzIPGroup -Verbose
$counter++
}
}

}
}

Note: Make sure your country matches the supported country shortcodes found here: IPBlock Aggregated. IPDeny is the source for the IP address list.

Once saved to your computer, it's time to import it into your active PowerShell terminal and run it (after you have verified you have connected to the correct Azure subscription).

So I will navigate to the script and import it:

cd D:\git
. .\New-AzCountryIPGroup.ps1
New-AzCountryIPGroup

Import New-AzCountryIPGroup.ps1

The 'New-AzCountryIPGroup' Azure function relies on 4 parameters:

ParametersValues
CountryCodeNZ
IPGroupNameIPGrpNZ
IPGroupRGNameNetworkRG
IPGroupLocationAustraliaEast

Make sure that the values change to your environment; in my example, I am specifying an IP Group and Resource Group that doesn't exist so that the script will create it for me - and the location I will be deploying to will be the Australia East region.

New-AzCountryIPGroup -CountryCode NZ -IPGroupName IPGrpNZ -IPGroupRGName NetworkRG -IPGroupLocation AustraliaEast

New-AzCountryIPGroup

As you can see, the script created an Azure Resource Group and imported the New Zealand IP ranges to a new IP Group...

Not required - but if I rerun it, it will simply override any IP addresses that are the same and add any new addresses to the same IP Group that already exists, as below:

Rerun New-AzCountryIPGroup

The Azure IP Group is visible in the Azure Portal as below:

Azure Portal - Azure IP Group

And a Tag was added to include the country:

Azure IP Group - Tag

As New Zealand was under the 5000 limit, only one IP Group was needed, but if we change the Country Code to the US...

Run New-AzCountryIPGroup - US

It created 5 IP groups, each containing 5000 CIDR IP ranges, with the last containing the remaining IP address ranges.

As you can see, it's reasonably easy to create IP Groups containing a list of IP ranges for multiple countries quickly:

Azure Portal - Azure IP Groups

Note: The script can also be found in my Public Git Repo here, feel free to recommend pull requests if you have anything to add or change.