Skip to content

Automating Desired State Configuration

Last updated on April 20, 2020

A case study on automagically deploying a Unifi Wi-Fi controller on Azure

The Coronavirus outbreak has many people working from home, myself included. An important aspect of a good home office is proper WiFi. Personally, I’m a big fan of Ubiquiti’s Unifi-series WiFi hardware. I have a couple of access points installed throughout my house and have long been using an Azure-hosted Linux VM to run the Wi-Fi controller software these AP’s require. I could just run that on my home PC, however, my MSDN-subscription’s Azure credits allow for a hobby project or two.

Mostly, WiFi controllers are things you just deploy and forget about. When I tried to login to mine last week I found my Linux VM was unreachable. Something with a forgotten password, disks that had clogged up with logs, and all kinds of commonly seen problems when you don’t log onto a VM for 2 years.

Since I currently work lot with Azure Automation and DSC I figured I’d clean this mess up and automate the deployment and maintenance of this controller.


What I’ll show you in this post is how I’ve automated the deployment of my Unifi WiFi controller. With this, you’ll have reference material when working with Azure Automation DSC and DevOps release pipelines.

Let’s get started

For this solution I used the following tools and resources:

  • Visual Studio Code with extensions:
    • Azure Resource Manager Tools
    • PowerShell
  • My MSDN Azure subscription
    • With a connected VPN gateway so I have site-to-site connectivity to my Azure resources from my home network
  • Azure DevOps (ADO)
  • GitKraken
  • The following Azure Resources:
    • 1 virtual machine with network connectivity to the VPN-vnet
    • 1 storage account
    • 1 key vault
    • 1 automation account
  • A powershell script by Kevin Timmerman to process ARM-output in ADO release pipelines which I modified to suit my preferences:
  • Chocolatey for installation of packages on a windows environment.

All my code is published on my GitHub repository and available for all to use.


A conceptual representation of what we’re building is this:

We start with a project created in ADO and project files uploaded into the repository. There is a YAML file in the github repository to help you set up your build pipeline. The build pipeline provides the artifact package which is used in the release pipeline.

The actual release pipeline in ADO looks like this:

And has the following tasks:

I created a sequence diagram with Mermaid which still needs some work ;). However, it does provide more detail on the design of the stage:

There’s a lot to unpack there. Mostly, I’m invoking scripts and ARM deployment tasks, passing information between them. It contains couple of things that are not necessary for a home WiFi-controller. For example, working with a generated password and enabling disk encryption. I added them, as I recommend including these features when working in a professional setting.

I only provide 5 parameters to deploy this solution, the rest is all generated in the release pipeline. These are declared in an ADO variable group:

Variable nameValueExplanation
adoAadObjectIdAzure AD Object ID of the Azure Devops Service Principal used for the deployment.Needed to write secrets to the key vault.
jllAadObjectIdMy own AAD object ID.So I can easily view the contents of the key vault after deployment.
solutionPrefixAny string <= 15 chars, no spaces or special characters.Used as prefix for resource naming.
subnetResourceIdSubnet resource IDUsed to attach the NIC to a network.
dscFilenamedscAutomateUnifi.ps1The filename of the DSC-script to be used.

Side note: For the IP configuration I use a static IP. My old Linux VM-controller ran at this IP and I want to try to reconnect my access points with my new controller. I wanted to avoid resetting the AP’s. Feel free to switch to any other IP in your vnet’s address space. (You can make it dynamic, however I do not recommend a dynamic IP for a Unifi Wi-Fi controller).

Stop talking, give me code!



After deploying this first version of the code to your environment you should have a Windows Server 2019 Core VM with the Unifi-controller software and its dependencies installed onto it. You should be able to connect to it via RDP.

The Unifi-controller software should also be up an running. You should be able to connect to the solution via https://<privateIpAddress>:8443. This is of course assuming you have a VPN connected to your Azure virtual network and you are not blocking this traffic with a firewall or network security group. You will see a certificate warning as we are using the default installation’s certificate for the SSL.

In a future post I might try to clean up the certificate warning and automate the restore of a backup of the controller’s configuration.

I wanted to share this cool hobby project, since I feel it has a lot of applications outside of just running a WiFi-controller. If you have questions or other feedback, feel free to contact me.

Update 24/03/2020: After some more testing and fiddling I changed 2 things to the solution:

  • Switched to a ‘regular’ Server 2019 because I encountered compatibility issues with Server 2019 Core. I adjusted the virtual machine size accordingly.
  • Added 2 tasks in the DSC-script to get the solution to run as a service after deployment. It should now be ready to go after a successful release.
Published inGuides

One Comment

  1. Jos Jos

    Great writeup!

Leave a Reply

Your email address will not be published. Required fields are marked *