Skip to main content

Command Palette

Search for a command to run...

Automating Azure NSG Inbound Rules for Dynamic IPs Using DDNS and PowerShell Runbooks

Maintain Azure NSG inbound security rules with a changing source public IP using a PowerShell Runbook and Dynamic DNS in Azure Automation.

Updated
8 min read
Automating Azure NSG Inbound Rules for Dynamic IPs Using DDNS and PowerShell Runbooks

Overview.

Managing inbound access to Azure resources through Network Security Groups (NSGs) is a standard best practice. NSGs define which IP addresses or ranges are permitted to communicate with your services, providing an essential layer of control for environments hosting management interfaces, firewalls, or Azure Virtual Desktop infrastructure.

The challenge arises when the authorised source WAN IP address changes frequently. This scenario is common for environments using DDNS, dynamic VPN gateways, partner networks, or externally managed endpoints.

Manually updating NSG rules to reflect a new source IP is both inefficient and prone to error.

In this article, I demonstrate how to automate NSG inbound security rule updates dynamically using a DNS hostname (for example, from Dynamic DNS), PowerShell, and Azure Automation. The result is a secure, credential-free automation that keeps your NSG rules continuously aligned with the current source IP address.


Understanding The Problem.

NSGs in Microsoft Azure operate at Layer 3 and Layer 4 of the network stack, enforcing allow or deny rules based on parameters such as source, destination, port, and protocol.

When the source address of a trusted endpoint changes, the corresponding rule must be updated to maintain connectivity.

For example, a VPN concentrator or external network may obtain a new public IP every few hours. Leaving the NSG source set to Any is insecure, yet manually updating the rule every time the IP changes is impractical.

As shown below, Azure NSG inbound security rules do not support Fully Qualified Domain Names (FQDNs) or hostnames. Only IP addresses or CIDR-based ranges can be used when defining the source or destination of a rule.

To handle frequently changing source addresses, Azure Automation can be used to periodically resolve a DNS record representing the authorised source and automatically update the NSG rule with the resolved IP.


Prerequisites.

Before implementing this solution, ensure the following requirements are met:

  1. Azure Subscription: Sufficient permissions to create resources and assign roles.

  2. Existing Network Security Group (NSG): Containing an inbound security rule that requires dynamic source IP management.

  3. DNS Hostname: A resolvable DNS record (for example, a DDNS hostname) that maps to the current public IP of the authorised network. I use a service called No-IP for this.

We will create:

  • An Azure Automation account.

  • A system-assigned managed identity.

  • A runbook, linked to a schedule.


Solution Overview.

The solution uses an Azure Automation Runbook to maintain NSG rules dynamically.

Your DNS hostname (for example, mynetwork.ddns.net) resolves to the current public IP of the trusted source. This could represent an office or home network that you access over VPN (for instance OpenVPN).

The Runbook executes a PowerShell script that:

  • Resolves the hostname to its current IP address.

  • Retrieves the NSG configuration.

  • Compares the existing rule source to the resolved IP.

  • Updates the rule only when a change is detected.

The Runbook authenticates to Azure using its Managed Identity, eliminating the need for credentials or secrets. This ensures that NSG rules remain accurate, secure, and automatically synchronised with DNS resolution.


Step 1/5: Creating The Azure Automation Account.

  1. In the Azure Portal, navigate to Automation Accounts → Create.

  2. On the Basics tab:

    1. Specify an Azure Subscription, and the resource group containing the NSG.

    2. Enter a name for the Automation Account.

    3. Choose the same region as your NSG.

  3. On the Advanced tab:

    1. Keep the managed identity selection as System assigned.
  4. On the Networking tab:

    1. Keep the connectivity configuration as Public access.
  5. Select Review + Create → Create.


Step 2/5: Configuring Permissions.

  1. Once the Automation Account has been created:

  2. Navigate to your NSG.

    1. In the Azure Portal, select the search bar and search for Network security groups and select your NSG.
  3. Select Access control (IAM) → Add → Add role assignment.

  4. On the Role tab:

    1. Select Network Contributor on page 4 → Next.
  5. On the Members tab:

    1. Choose Managed Identity → Select members → Automation Account → and select the name of the automation account that you created in step 1.

    2. Select Review + Assign to complete the assignment.

This grants the Automation Account permission to modify NSG rules using least-privilege access.


Step 3/5: Creating The PowerShell Runbook.

Below is the production-ready PowerShell script that performs the dynamic update.

It authenticates using a Managed Identity, resolves the DNS hostname, retrieves the NSG inbound security rule, and applies changes only when the source IP differs.

param(
    [string]$ResourceGroupName = "PutYourResourceGroupNameHere",
    [string]$NsgName = "PutYourNetworkSecurityGroupNameHere",
    [string]$RuleName = "PutYourRuleNameHere",
    [string]$DnsName = "PutYourDDNSorFQDNHere"
)

# Log start
Write-Output "Starting NSG update process for $DnsName"

# Authenticate with the system-assigned managed identity
Connect-AzAccount -Identity

# Resolve DDNS hostname to IP
try {
    $resolvedIP = (Resolve-DnsName -Name $DnsName -Type A).IPAddress
    Write-Output "Resolved IP: $resolvedIP"
} catch {
    Write-Error "Failed to resolve $DnsName"
    exit 1
}

# Retrieve the NSG
try {
    $nsg = Get-AzNetworkSecurityGroup -Name $NsgName -ResourceGroupName $ResourceGroupName
} catch {
    Write-Error "Failed to get NSG $NsgName from $ResourceGroupName"
    exit 1
}

# Retrieve the rule
$rule = $nsg.SecurityRules | Where-Object { $_.Name -eq $RuleName }

if (-not $rule) {
    Write-Error "Rule '$RuleName' not found in NSG '$NsgName'"
    exit 1
}

# Get current source
$currentSource = if ($rule.SourceAddressPrefix -is [System.Array]) {
    $rule.SourceAddressPrefix -join ","
} else {
    $rule.SourceAddressPrefix
}

# Compare and update if required
if ($currentSource -ne $resolvedIP) {
    Write-Output "Updating rule '$RuleName' SourceAddressPrefix from '$currentSource' to '$resolvedIP'"

    try {
        # Properly modify the NSG rule
        $nsg | Set-AzNetworkSecurityRuleConfig `
            -Name $RuleName `
            -Protocol $rule.Protocol `
            -Direction $rule.Direction `
            -Priority $rule.Priority `
            -SourceAddressPrefix $resolvedIP `
            -SourcePortRange $rule.SourcePortRange `
            -DestinationAddressPrefix $rule.DestinationAddressPrefix `
            -DestinationPortRange $rule.DestinationPortRange `
            -Access $rule.Access

        # Commit the update to Azure
        Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsg
        Write-Output "Update complete. Rule '$RuleName' now allows only $resolvedIP."
    } catch {
        Write-Error "Failed to update rule '$RuleName': $_"
        exit 1
    }
} else {
    Write-Output "No change detected. Current IP already matches."
}

Ensure you replace the placeholder variables ($ResourceGroupName, $NsgName, $RuleName, $DnsName) at the top of the script.


Step 4/5: Publishing The Automation Runbook.

  1. In the Azure portal, navigate to Automation Accounts → Process Automation → Runbooks.

  2. Select Create a Runbook.

  1. Provide a name, and choose Powershell as the Runbook type.

  2. Choose 7.2 (or later) as the Runtime version.

  3. Select Review + Create → Create.

  4. Then, open the runbook, and select Edit → Edit in portal.

  5. Paste the above PowerShell code, and change the variables as highlighted previously.

  6. Choose Save, and then select Test in pane.

If your inbound security rule currently has its source set to Any, a successful test should replace it with the resolved IP address.

Example result:

Example output:

Completed
Starting NSG update process for [REDACTED].ddns.net

Environments                                                                                           Context
------------                                                                                           -------
{[AzureCloud, AzureCloud], [AzureUSGovernment, AzureUSGovernment], [AzureChinaCloud, AzureChinaCloud]} Microsoft.Azure.…

Resolved IP: [REDACTED]
Resolved IP: [REDACTED]
No change detected. Current IP already matches.

Once verified, publish the Runbook.


Step 5/5: Scheduling The Runbook.

Finally, schedule the Runbook to ensure it runs automatically. In this example, I will schedule the runbook to run every hour.

  1. Ensure that your runbook is in a published state:

  1. Select the runbook → Link to schedule → Schedule (Link a schedule to your runbook).

  2. Choose Add a schedule.

  3. Name the schedule.

  4. Set the start date.

  5. Select Recurring.

  6. Set the recur to 1 Hour.

  7. Set the expiration (if needed).

  8. Select Create.


Verification.

After the first scheduled runbook execution, check the NSG in the Azure Portal under Inbound security rules. You should see that the rule’s Source field reflects the current IP resolved from your DNS hostname.

You will also see the scheduled run in the Overview page, under recent jobs.


Example Scenario.

To illustrate this automation in practice, consider the following real-world use case.

I have deployed a Sophos Firewall (SFOS) virtual appliance in Microsoft Azure. This appliance provides both a Management, User Portal and a VPN Portal, typically accessible on TCP ports 443, 4443 and 4444 by default. While these portals can be essential for administrative and remote user access, exposing them directly to the public internet is not recommended.

From a security and compliance standpoint, unrestricted WAN exposure conflicts with:

  • Cyber Essentials requirements for minimising externally exposed management interfaces.

  • NCSC Cloud Security Principles, which advise strict control over administrative interfaces.

  • NIST SP 800-41 and 800-125 guidelines, which recommend that VPN and firewall management endpoints are not accessible from untrusted networks.

In this scenario, I want to securely manage and access the Sophos Firewall without exposing the User or VPN portals to the WAN.

However, my office network connection uses a dynamic public IP address provided by my ISP. This means the IP changes periodically, breaking any static NSG rule that restricts inbound access.

To address this, I use a Dynamic DNS (DDNS) hostname, for example vpn.ddns.net, which always points to my home network’s current IP address. I can connect to my network at any time using OpenVPN, but since Azure Network Security Groups do not support FQDNs or DDNS resolution natively, the NSG cannot reference vpn.ddns.net directly.

Instead, the Azure Automation Runbook dynamically resolves the DDNS hostname and updates the inbound NSG rule for the Sophos firewall. This ensures that:

  • Only my current, trusted office IP address is permitted inbound access to the VPN and User Portals.

  • The firewall remains effectively non-public, in compliance with Cyber Essentials, NCSC, and NIST best practices.

  • The automation continuously maintains secure access without manual intervention each time my IP changes.

This approach combines least-privilege network access with automation and identity-based security, removing both administrative overhead and risk exposure.


Conclusion.

Automating NSG rule updates with Azure Automation and PowerShell provides an elegant and secure solution to managing dynamic inbound access.

By resolving a DNS hostname and applying the corresponding IP address to your Network Security Group rule, you eliminate the need for manual intervention while maintaining the principle of least privilege.

This method is lightweight, cost-effective, and entirely managed within the Azure platform. It scales easily to multiple environments, supports credential-free authentication via Managed Identity, and can be extended with monitoring, notifications, or audit logging for enterprise-grade governance.

Whether you are managing Azure Virtual Desktop session hosts, VPN gateways, or administrative endpoints, this approach ensures continuous and secure access control without compromising operational efficiency.