DNS Load Balancing in Azure

Posted on Updated on

Reading Time: 3 minutes

This post won’t be too long, but I wanted to expand a bit on the recent repo that I published to Github for Azure Load Balanced DNS Servers. I’ve been working in Azure the better part of a decade and the way we’ve typically approached DNS is in one of two ways. Either use (a pair of) IaaS Domain Controllers or use Azure-Provided DNS resolution. In the last year or so there have been an increasing number of architectural patterns that require private DNS resolution where it we may not necessarily care about the servers themselves.

This pattern has become especially popular with the requirements for Azure Private Link in hybrid scenarios where on-premises systems need to communicate with Azure PaaS services over private link.

Reference: https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns#on-premises-workloads-using-a-dns-forwarder

The only thing the DNS forwarder is providing here is very basic DNS forwarding functionality. This is not to say that it can’t be further configured, but the same principles still apply. DNS isn’t something that needs any sort of complex failover during patch windows, but since it has to be referenced by IP we have to be careful about taking DNS servers down if there aren’t alternates configured. With a Web Server we would just put it behind a Load Balancer, but there don’t seem to be configurations published for a similar setup with DNS servers (other than using a Network Virtual Appliance) since UDP isn’t a supported health probe by Azure Load Balancers. How then do we configure a pair of “zero-touch” private DNS functionality in Azure?

When asked “What port does DNS use?”, the overwhelming majority of IT Professionals will say “UDP 53”. While that is correct, it also uses TCP 53. UDP Packets can’t be larger than 512 Bytes, and while this suffices in most cases for DNS there are certain scenarios where it does not. For example, DNS Zone Transfers (AFXR/IFXR), DNSSEC, and EDNS all have response sizes larger than 512 bytes, which is why they use TCP. This is why the DNS Service does (be default) listen on TCP 53, which is what we can use as the health probe in the Azure Load Balancer.

The solution that I’ve published on Github (https://github.com/matthansen0/azure-dnslb), contains the template to deploy this solution which has the following configuration.

  • Azure Virtual Network
  • 2x Windows Core Servers:
    • Availability Set
    • PowerShell Script to Configure Servers with DNS
    • Forwarder set to Azure Multicast DNS Resolver
  • Azure Load Balancer:
    • TCP 53 Health Probe
    • UDP/TCP 53 Listener
Azure DNS Load Balanced Solution

This template does not include patch management, but I would highly recommend using Azure Update Management, this way you can setup auto-patching and an alternate reboot schedule. If this is enabled, this solution would be a zero-touch, highly-available, private DNS solution for ~$55/mo (assuming D1 v2 VM, which can be lower if a cheaper SKU is chosen).

Since I’m talking about DNS here, the last recommendation that I’ll make is to go take a look at Azure Defender for DNS which monitors, and can alert you to suspicious activity in your DNS queries.

Alright, that’s it! I hope this solution will be helpful, and if there are options or configurations you’d like to see available in the Github repository please feel free to submit an issue or a PR! If you want to deploy it right from here, click the button below!

Deploy to Azure

 

If you have any questions, comments, or suggestions for future blog posts please feel free to comment blow, or reach out on LinkedIn or Twitter. I hope I’ve made your day a little bit easier!

5 thoughts on “DNS Load Balancing in Azure

    […] *Note* You can also check out my post on automated IaaS DNS Load Balancing to help with the private, hybrid DNS integration scenarios that may be required for Private Link here: DNS Load Balancing in Azure. […]

    Bryan OReilly said:
    January 12, 2022 at 9:47 pm

    This article was great. this is exactly what I was looking for. I have one question as i am still new to Azure templates. Do you have a version of your template when you can instead of creation a vnet, instead select an existing Vnet\subtnet ? I tried for a while and just could not get it to work.

      Matt Hansen responded:
      January 14, 2022 at 6:16 am

      Yes, if you go directly to the github repo (https://github.com/matthansen0/azure-dnslb) there is an option to deploy into an existing vnet.

        Bryan said:
        January 14, 2022 at 3:51 pm

        Thank you very much. I will compare the templates and attempt to educate myself. Thank you very much again.

    Mark Martin said:
    January 21, 2022 at 9:00 am

    Thanks for your work on this. I implemented this for our setup and resolution worked as expected when the LB IP is directly queried from the client. In our design, we use on premises existing DNS servers as the resolvers configured on the Azure clients. When we setup conditional forwarding for our Azure zone (call it “azure.contoso.com”) on our on premises resolvers to point to this load balanced DNS forwarder setup in Azure, resolution did not work until I setup conditional forwarding for “azure.contoso.com” on our Azure forwarders to the Azure provided DNS. Any idea why this is needed?

Leave a Reply to Bryan OReillyCancel reply