Breaking Down a Monolith – Static MAC address licensing in Azure

Many antiquated established software companies have tied their licensing to the MAC ADD of your server/computer. This causes a slew of issues.  To name a few: replacing hardware in your servers, running multiple network cards (think redundancy), virtualizing your environment, or even just setting up a highly available configuration of your application. In my use case with a customer, we had to reach out directly to the software vendor to re-install our application, request a new license and wait almost an entire day to provide the license file.  It is a time consuming process.  There is nothing agile about this process.

I have recently been working on a customer project that was a ‘simple migration to the cloud’, migrating their on premises physical server and its applications to Azure. While that can be straight forward as you can do a ‘lift and shift’ that doesn’t really enable the application nor the customer to fully embrace the capability of the cloud. The customer wanted an automated and repeatable solution to rid themselves of various pain points in their current system.

Designing for the new cloud infrastructure we highlighted the technical blockers of migration their production system to the cloud. Our biggest blocker was the licensing for two of the applications, each license was tied to the MAC address and machine name of the physical server. The licensing setup was also tedious to configure and took over a day to setup. You had to provide the vendor with your MAC address, which was then embedded into their license file. The server had to provide the licenses to 2 running virtual machines, one Linux and one Windows, which had to be spun up simultaneously and communicate for the applications to work.

Overview of the technical considerations:

  • Licensing requirements for the applications, dependency on a dedicated licensing server with a static MAC address
  • Breaking up a single physical server running several applications
  • A Windows and Linux VM that must run simultaneously

While there are various dependencies in this project, I was focused on the license component. This was treated like the most fragile egg. No one wanted to touch it, change it, or breathe around it. We originally opted to keep the license server as a static server, running 24/7/365 in Azure. While that’s an easy ‘lift and shift’ solution, that doesn’t break down the full monolith, nor does it really leverage the cloud. Our end goal was to build a fully automated system using CI/CD. So…we found a workaround.

The first thing we did was build a Windows virtual machine in Azure and configured the license server manually. Documenting all of the components of the install and configuration. We obtained our licenses from the vendors, using the assigned MAC address and server name. In order to break down this monolith, we needed to put forth the upfront effort to understand where ALL of the pain points in the system existed.

The good news is that the license server was up and running in Azure, along with the other virtual machines. The customer at this point was ecstatic, they were using the cloud, something they once thought was not achievable. We didn’t stop there…

We began to automate the infrastructure, implement CI/CD with Azure DevOps. Deploying the entire infrastructure with Terraform, embracing Infrastructure as Code, except for that pesky license server. The blockers around the license server were still there. We had to find a way for the customer to be more agile.

Azure assigns the MAC address to your NIC, if you destroy your VM you cannot designate the preferred MAC address like you would an IP address. But…there’s a workaround…when you delete a virtual machine in Azure, the disks and NIC are left behind. We could have easily just re-deployed a new virtual machine, using the former disks and NICs. That way the MAC address wouldn’t change and we wouldn’t have to reinstall our software.

We had another issue. We built the license server in a vNET, which we used for a test platform, it was not production ready. The customer had implemented Azure Policy and standardized naming conventions for the new production environment. We needed to migrate our license server to a new vNET. Slight problem, NICs cannot migrate across vNETs. Meaning, we would have to deploy a brand new NIC to our VM, and if we ever wanted to move vNETs again, this would be an issue.

At this point, I looked at ways to ‘spoof’ the MAC address. If we could build a new virtual machine, using our existing disks and manually configure the MAC address, we would not be blocked by the licensing requirements. That’s exactly what I did.

We deployed our virtual machine into the new vNET, using our previous disks (which retains the original Windows machine name), and setting up a loop with the NICs and set the MAC address to match what is in our license file. Finally, a resolution to this blocker! Here’s how it was executed…

Creating a NIC and Manually Configuring the MAC Address

In building the virtual machine, we assigned it 2 NICs. The primary NIC was assigned to the desired vNET and subnet. Then we powered down the machine and added a second NIC. Note: If you have a previously created NIC that you can use, you can reassign it here. Because we had to move vNETs, we couldn’t re-use our previous NIC. For the future state of this project, we are using the same NICs in the rebuild, avoiding having to recreate them (but we could if we had to).

  1. Create your virtual machine, attach your previous disks (or use new if OS and data disks are not an issue). In our case we needed to ‘attach a previous disk’ to maintain the OS build, installations and machine name. 

2. Configure the VM resource as required for your organization (tagging, etc.)

3. Complete the virtual machine build. Note: we did this manually, but in our future state this is done directly from Terraform as part of the CI/CD build.

Once the virtual machine builds successfully, you will have attached the original license server disks. You will have also created a brand new NIC.  You will need to add a second NIC or attach the previous NIC.

NIC setup and MAC address assignment

1. Once the machine is built, shut it down, as it will need to be powered off to perform the next steps.

2. Once powered down, navigate to the virtual machine: ‘settings’ > ‘Networking’. Select ‘Attach Network Interface’. Select the former NIC from the previously built server. Note, we couldn’t move the NIC, but if you are working in the same vNET, this is were you will attach a working NIC. 

3. Once the NIC is attached, proceed to step 5. If you have to assign a new NIC, go to step 4.

4. In the case that there is not a previous NIC to assign, create a new resource from the portal in Azure. Create a new ‘Network interface’. Configure the network interface with the vNET and configuration details that you require. Attach the newly created network interface to the VM by navigating back to the VM networking configuration in step 2. Once completed, go to step 5.

5. Power on the virtual machine. The virtual machine will have the new name assigned in the Azure portal, but in our case, we re-purposed the original hard disks, thus the Windows machine name persisted on the OS disks. For our purpose, the machine name was also embedded in the license file. Log into the server and navigate to the ‘device manager’:

-Start > Search > type in ‘Device Manager’

-Press ‘Windows + x’ and select ‘Device Manager’

-Press ‘Windows + r’ and type ‘devmgmt.msc’

6. Navigate to ‘Network Adapters’ and select the arrow to expand the icon. There will be 2 ‘Hyper-V Virtual Ethernet Adpater’s listed. Right click the one noted with ‘#2’ or the the one with the higher number (i.e. virtual network adapter #5 and virtual network adapter #6), the higher numbered one will be the second NIC that you have recently attached.

Right click on the network adapter #2 (or higher numbered) and select ‘properties’. Select the ‘Advanced’ tab.

7. Select ‘Network Address’ and tick the item that reads ‘Value’. Copy and paste the MAC address that is required for the licensing. 

8. Select ‘okay’

9. You have successfully created/attached a second NIC and configured the MAC address for that NIC as a loopback for the virtual machine.

To confirm that the MAC address was assigned correctly, open a cmd prompt or PowerShell window and type: ‘ipconfig /all’

You should see the new MAC address assigned to the ethernet adapter.

We have effectively created a loop in the networking. Forcing the assignment of the MAC address. As soon as we booted up the license server and connected the applications, we could connect and run the applications without any issues. You might be asking, ‘why can’t I just manually assign the MAC address to the primary NIC and have one NIC?’ It doesn’t work, the way the SDN in Azure is configured it breaks the networking, hence why we need to create a loop with 2 NICs.

Automating the MAC Address Assignment

What we did above was a manual process, we wanted to automate this. We are able to deploy our virtual machine with Terraform, then adding a task to our CI/CD pipeline using PowerShell

Set-NetAdapterAdvancedProperty -Name 'Private Team' -DisplayName 'MAC Address' -DisplayValue '00-00-00-00-00-00'

Note: You may have to remove the dashes from the desired MAC address

Next step: we can now destroy and rebuild the virtual machine (keeping the NIC and disks in tact) at the same time as the other environments. We have taken a monolithic system, broken down the components and made it completely repeatable. We were able to remove the technical blokers that the software vendors created for us and ended up with a very happy and agile customer.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s