When you’re connecting a home (or perhaps even an office) lab to Azure with a site-2-site VPN you’ll probably have to deal with the fact that you have a dynamic IP assigned by your ISP. This means unless you update the VPN Gateway Address of your Azure local network in some automated way, your connection is down very often.

A fellow MVP of mine (Christopher Keyaert) has written a PowerShell script that a few years back that updated the VPN gateway address of your Azure local network via a scheduled task inside of his Windows RRAS VM. Any VM, either in Azure or in your lab will do. Good stuff! If you need inspiration for a script you have a link. But, I never liked the fact that keeping my Azure site-to-site VPN up and running was tied to a VM being on line in Azure or in my lab, which is also why I switched to a SonicWALL device. Since we have Azure Automation runbooks at our disposal I decided to automate the updating of the VPN gateway address to the dynamic IP address of my ISP using a runbook.

 

PowerShell
Edit|Remove
<#     
    .NOTES 
     Created on:       21/03/2015 18:28 
     Created by:       Didier Van Hoye 
     Organization:  WorkingHardInIT 
     Blogs: http://blog.workinghardinit.work & http:/workinghardinit.wordpress.com 
     Purpose:         Azure Scheduled Runbook To Update 
                    Dynamic IP Address site-to-site VPN 
#> 
 
workflow updatedynipvpn 
{ 
    <# 
    Connect to my subscription. I have set up an automation account for this. 
    See for more infor on how to do this. 
    #> 
    $Cred = Get-AutomationPSCredential -name "user@youraccount.onmicrosoft.com" 
    Add-AzureAccount –Credential $Cred 
    $AzureSubscriptionName = "Visual Studio Ultimate with MSDN" #change to your. I'm using my MSDN benefits in the lab. 
    Write-Output "Connecting to subscription:  $AzureSubscriptionName" 
    Select-AzureSubscription -SubscriptionName $AzureSubscriptionName 
     
    inlinescript 
    {     
        <# 
        Grab the current dynamic IP address of my home lab via the FQDN 
        registered for this purpose with my free dynamic IP provider  
        #> 
        $DynDNS = "mydynamicdnsname.dynamic-dns.net" #change to yours 
        #Get IP based on the Domain Name 
        [string]$MyDynamicIP = ([System.Net.DNS]::GetHostAddresses($DynDNS)).IPAddressToString 
        write-output "Your current dynamic local VPN IP is: $MyDynamicIP" 
                 
        #Read the current network configuration & dumpt it into an XML variable 
        $XML = Get-AzureVNetConfig 
        [xml]$ReadCurrentAzureVNetConfig = $XML.XMLConfiguration 
         
        #the name of the local network I want to update. Very important if you have more than one. 
        $MyLocalSoHoNetworkInAzure = "yourlocalnetworkname" 
         
        #Get the IP addres of the VPN gateway for the specified local network 
        [string]$MyAzureVPNGatewayIP = ($ReadCurrentAzureVNetConfig.DocumentElement.VirtualNetworkConfiguration.LocalNetworkSites.LocalNetworkSite | where { $_.name -eq $MyLocalSoHoNetworkInAzure }).VPNGatewayaddress 
        write-output "Current Azure VPN Gateway Address IP for $MyLocalSoHoNetworkInAzure is :  $MyAzureVPNGatewayIP" 
                     
        #Check if you need to update your Azure VPN Gateway IP address 
        if ($MyDynamicIP -ne $MyAzureVPNGatewayIP) 
        { 
            #You have a new dynamic IP address so you'll update the local network VPN gateway in Azure 
            Write-Output "Updating your Local Network $MyLocalSoHoNetworkInAzure VPN Gateway Address ..." 
             
            #Update the configuration in our XML variable 
            ($ReadCurrentAzureVNetConfig.DocumentElement.VirtualNetworkConfiguration.LocalNetworkSites.LocalNetworkSite | where { $_.name -eq $MyLocalSoHoNetworkInAzure }).VPNGatewayaddress = $MyDynamicIP 
             
            <# 
               Create a temp file to pass the adjusted config to Set-AzureVNetConfig, 
               which require a file for the mandatory -ConfigurationPath parameter 
            Thanks for the tip Stijn Callebaut! 
            #> 
            $NewAzureVNetConfigFile = [System.IO.Path]::GetTempFileName() 
             
            #Update the configuration file to the temp file ... we need this as we need to pass a file to Set-AzureVNetConfig 
            $ReadCurrentAzureVNetConfig.Save("$NewAzureVNetConfigFile") 
             
            #Update your virtual network settings 
            $ReturnValue = Set-AzureVNetConfig -ConfigurationPath $NewAzureVNetConfigFile 
             
            if ($ReturnValue.OperationStatus -eq "Succeeded") 
            { 
                Write-Output "SUCCESS! Your Local Network $MyLocalSoHoNetworkInAzure VPN Gateway Address was updated ." 
                Write-Output "$MyLocalSoHoNetworkInAzure VPN Gateway Address was updated from $MyAzureVPNGatewayIP to $MyDynamicIP" 
            } 
            else 
            { 
                Write-Output "FAILURE! Your Local Network $MyLocalSoHoNetworkInAzure VPN Gateway Address was NOT updated." 
            } 
             
        } 
        else 
        { 
            #You did not get a new dynamic IP yet, nothing to do 
            Write-Output "Nothing to do! Your Local Network $MyLocalSoHoNetworkInAzure VPN Gateway Address is already up to date." 
        } 
    } 
}
 

Finding out your dynamic IP address from anywhere in the world

For this to work you need a way to find out what your currently assigned dynamic IP is. For that I subscribe to a free service providing dynamic DNS updates. I use https://www.changeip.com/. That means that by looking up the FQDN is find can out my current dynamic IP address form where ever I have internet access. As my SonicWALL supports dynamic DNS services providers I can configure it there, no need for an update client running in a VM or so.

The runbook to update the VPN Gateway Address of your Azure local network

I will not deal with how to set up Azure Automation, just follow this link. I will share a little hurdle I needed to take. At least for me it was a hurdle. That hurdle was that the Set-AzureVNetConfig cmdlet which we need has a mandatory parameter -ConfigurationPath which reads the configuration to set from an XML file (see Azure Virtual Network Configuration Schema).

You cannot just use a file path in an Azure runbook to dump a file on c:\temp for example. Using an Azure file share seems overly complicated for this job. After pinging some fellow MVPs at Inovativ Belgium who are deep into Azure automation on a daily basis, Stijn Callebaut gave me the tip to use [System.IO.Path]::GetTempFileName() and that got my script working. Thank you Stijn !

So I now have a scheduled runbook that automatically updates my to the dynamic IP address my ISP renews every so often without needing to have a script running scheduled inside a VM. I don’t always need a VM running but I do need that VPN to be there for other use cases. This is as elegant of a solution that I could come up with.

I test the script before publishing & scheduling it by setting the VPN Gateway Address of my Azure local network to a wrong IP address in order to see whether the runbook changes it to the current one it got from my dynamic IP.

Now publish it and have it run x times a day … depending on how aggressive your ISP renews your IP address and how long your lab can sustain the Azure site-to-site VPN to be down. I do it hourly. Not a production ready solution, but neither is a dynamic IP and this is just my home lab! Now my VPN looks happy most of the time automatically