When working with customers on consulting engagements, it is often useful to have the capability to setup and provision test systems, to help accelerate your own learning and understanding of a new product, or work through a problem.
I have a small home lab that I use to support home based services (IoT devices, WiFi), personal projects, and the occasional work thing. In addition, I have a number of Cloud accounts (AWS, Azure, GCP, Packet.net), that I use to support more work focused activities. This flexibility works well, but it does mean I sometimes have a complex arrangement of distributed systems. To help bring some degree of order to the chaos, I use DNS zones, and delegate subdomains out to each cloud provider. This provides a standards based, well understood, and easy to manage approach to addressing each system, without the burden of running an end-to-end DNS solution. The following diagram describes this setup.
Here's how I do it, using AWS and Azure as an example.
As always, this works for me, YMMV. It may not be the best idea, and there may be a much better approach out there, but for my simple brain it makes my life easier. Use or don't at your own risk.
First off, you're going to need a proper, bought and paid for, domain name. eg
my-awesome-site.com, whatever. Go buy one from any of the usual suspects, GoDaddy, domains.google, Fasthosts, etc.
As I use AWS for a lot of the above hackery, I was super lazy and simply bought one from within the Route53 console. My domain is
Presuming you have the same use case as me, you'll need your Cloud Provider credentials. Be aware that just like any cloud service, using the DNS services costs cash, but it is pennies per record, so shouldn't be too harmful to your wallet.
In whatever tool manages your root domain (AWS Route53 here), take a look in the Hosted Zone for your chosen domain. In my example, this is
portalvein.io and the hosted zone was auto-created by the AWS Registrar. (Hosted Zone is AWS terminology, and hence other providers may use an different term for the same thing. Azure calls these DNS Zones).
Inside the hosted zone, you'll see the usual domain anchors, with a Start of Authority (SOA) and Name Server (NS) record.
Create Delegated SubDomain (AWS)
I'm going to delegate a subdomain
ether.portalvein.io to a different AWS account (my work one).
Login and navigate to the AWS Route53 console.
Create a hosted zone that reflects your delegated subdomain. If you've not created a subdomain for your domain before, AWS will need to confirm you own your top level domain.
Once created, take a look at the zone. Once again, you should see the standard domain anchors of SOA and NS.
Make a note of the NS record entries, as we'll need these to add a NS record within our Top Level Domain to handle the delegation.
Create NS Record for AWS SubDomain
Once you've created the hosted zone, head back to your top level domain. We need to create a Name Server (NS) record which tells clients which DNS servers are authoritative for the
All we are doing here, is creating a record informing any clients, that the Name Servers listed, are managing all records within
ether.portalvein.io, and hence the client will need to query these.
Create Delegated SubDomain (Azure)
OK, so we've set things up for AWS, lets now add the same for Azure.
Login to the Azure portal, and create a DNS Zone that represents the subdomain we wish to delegate.
Azure groups resources into a Resource Group, which in the following example is pre-created. The Name is the delegated zone name, in my example
Once created, take a look at the Zone. Similarly to AWS, you'll see the standard anchor records (SOA & NS).
Again, take a note of the contents of the NS record, as we'll need these entries to add to our top level domain.
Create NS Record for Azure SubDomain
Rinse and repeat. Go back to your top level domain, and create a Name Server (NS) record which tells clients which DNS servers are authoritative for the
Test It Out
So we've created all the needed records, lets run some tests. Here I'm using
dig to query and retrieve DNS resource records.
Name Server Records for
Should be AWS...
$ dig NS portalvein.io ; <<>> DiG 9.10.6 <<>> NS portalvein.io ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3266 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 2 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;portalvein.io. IN NS ;; ANSWER SECTION: portalvein.io. 86400 IN NS ns-1835.awsdns-37.co.uk. portalvein.io. 86400 IN NS ns-1399.awsdns-46.org. portalvein.io. 86400 IN NS ns-85.awsdns-10.com. portalvein.io. 86400 IN NS ns-936.awsdns-53.net. ;; ADDITIONAL SECTION: ns-936.awsdns-53.net. 17988 IN A 188.8.131.52 ;; Query time: 612 msec ;; SERVER: 10.200.1.13#53(10.200.1.13) ;; WHEN: Tue Apr 28 12:53:09 BST 2020 ;; MSG SIZE rcvd: 197
Name Server Records for
Should also be AWS...
$ dig NS +noall +answer ether.portalvein.io ether.portalvein.io. 178 IN NS ns-867.awsdns-44.net. ether.portalvein.io. 178 IN NS ns-1533.awsdns-63.org. ether.portalvein.io. 178 IN NS ns-409.awsdns-51.com. ether.portalvein.io. 178 IN NS ns-1746.awsdns-26.co.uk.
Name Server Records for
Should be Azure...
$ dig NS +noall +answer thrush.portalvein.io thrush.portalvein.io. 201 IN NS ns1-07.azure-dns.com. thrush.portalvein.io. 201 IN NS ns2-07.azure-dns.net. thrush.portalvein.io. 201 IN NS ns4-07.azure-dns.info. thrush.portalvein.io. 201 IN NS ns3-07.azure-dns.org.
OK, so each provider is now managing DNS for each subdomain.
For simplicity to test, I've simply created a fake A record within each subdomain, that I could then attach to a service endpoint or VM within each provider. Lets query these.
$ dig ec2.ether.portalvein.io ; <<>> DiG 9.10.6 <<>> ec2.ether.portalvein.io ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36229 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;ec2.ether.portalvein.io. IN A ;; ANSWER SECTION: ec2.ether.portalvein.io. 300 IN A 10.10.20.1 ;; AUTHORITY SECTION: ether.portalvein.io. 300 IN NS ns-409.awsdns-51.com. ether.portalvein.io. 300 IN NS ns-867.awsdns-44.net. ether.portalvein.io. 300 IN NS ns-1746.awsdns-26.co.uk. ether.portalvein.io. 300 IN NS ns-1533.awsdns-63.org. ;; Query time: 41 msec ;; SERVER: 10.200.1.13#53(10.200.1.13) ;; WHEN: Tue Apr 28 13:10:11 BST 2020 ;; MSG SIZE rcvd: 208
Note the IP address returned in the ANSWER section is
10.10.20.1 and has been returned by AWS DNS servers.
$ dig azure1.thrush.portalvein.io ; <<>> DiG 9.10.6 <<>> azure1.thrush.portalvein.io ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31956 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 5 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;azure1.thrush.portalvein.io. IN A ;; ANSWER SECTION: azure1.thrush.portalvein.io. 3600 IN A 10.10.10.1 ;; AUTHORITY SECTION: thrush.portalvein.io. 300 IN NS ns3-07.azure-dns.org. thrush.portalvein.io. 300 IN NS ns4-07.azure-dns.info. thrush.portalvein.io. 300 IN NS ns2-07.azure-dns.net. thrush.portalvein.io. 300 IN NS ns1-07.azure-dns.com. ;; ADDITIONAL SECTION: ns1-07.azure-dns.com. 165451 IN A 184.108.40.206 ns3-07.azure-dns.org. 7700 IN A 220.127.116.11 ns1-07.azure-dns.com. 165451 IN AAAA 2603:1061::7 ns3-07.azure-dns.org. 7700 IN AAAA 2a01:111:4000::7 ;; Query time: 603 msec ;; SERVER: 10.200.1.13#53(10.200.1.13) ;; WHEN: Tue Apr 28 13:08:47 BST 2020 ;; MSG SIZE rcvd: 297
Note that the IP address returned in the ANSWER section is
10.10.10.1 and has been returned by Azure DNS servers.
So hope that was useful. In this blog we quickly looked at and setup delegated DNS zones with two popular cloud providers.
Using DNS in this way allows you to simply and cleanly separate networks into mangeable zones based upon location, region or business function, that can easily scale, without lots of admin headache.
Extending this to cover other providers, and internal DNS solutions is simple, just follow the steps described, mapping each subdomain into each provider, or another cloud or on-premise solution. I currently delegate subdomains for my internal LAN to a BIND server in exactly the same way.
As we're nearly always standing on the shoulders of those that have done this before, I found the following articles, blogs and documentation useful when setting this up.