Every now and then I want to actually touch a technology rather than just reading about it all the time. This week it was about EntraID Hybrid environments – the bridge between traditional on-premises active directory and Microsoft EntraID (formerly known as Azure AD). I wanted to create a working environment where on-prem user accounts sync up into my Entra tenant, so I could poke around, break it and understand how the pieces fit into the whole picture.
The obvious way to build a lab like this would be to have a Domain Controller VM running on your premises somewhere on a type 1 hypervisor. But I didn’t want to dedicate my physical homelab servers resources for this (I’m running out of RAM on that lab machine) and setting up a dedicated laptop for that was more friction than the lab was worth.
So I settled on a slightly counter intuitive thing instead. I decided to build a “on-premises” Active Directory entirely in Azure, and synced it back up into EntraID – also in Azure.
First it sounds like a paradox, but understanding why it isn’t one is a very useful thing that I want to capture in this post.
/the mental model that makes this work
Here was the idea that changed my thinking from before: to EntraID, a “on-premises” doesn’t mean a physical location somewhere. It just means a traditional Active Directory Domain Services (AD DS), as opposed to cloud-native EntraID.
A domain controller running on an Azure VM is, from EntraID’s point of view, completely the same and indistinguishable from one sitting on my homelab server under my desk. The syncing tool used for a Hybrid environment – Microsoft Entra Connect – just needs a Windows AD domain to read from and an outbound HTTPS to reach EntraID. It does not know and does frankly not care, that the Windows AD Server, that is my “on-prem” DC happens to also run on an Azure data center in Switzerland.
The word “on-prem” is not the geography, it is about technology.
So once that clicked, I layed out my plan:
1. Create a Windows VM in Azure, promote it to a domain controller (also runs DNS)
2. Have a EntraID Tenant for testing purposes (which I already have for my labs)
3. Install Microsoft Entra Connect on the DC, syncing AD users up into the tenant
4. Test out possibilities of a Hybrid AD
Lets build it.
/phase 1 – the domain controller VM
I created a single Windows Server 2019 VM in the Azure Portal. A few points I want to highlight for this VM:
Size: B2ms (2vCPU / 8 GB RAM). You could technically promote a smaller sized VM, but regarding the fact that this one will run AD DS, DNS and EntraID Connect sync engine all at once, I just wanted to make sure to have enough power. The 4 GB limit with, for example a B2s ,would get cramped.
Networking: own VNet. I created a Hub-and-Spoke vnet and placed my DC in the Hub for this project. I pointed that Vnet’s DNS to this DC aswell, more on that later.
RDP locked to my IP. The VM creation wizard in the portal cheerfully offers to “allow RDP (3889)” and by default that means from the entire internet:

An exposed RDP port gets found and brute-forced within seconds, this is not hypothetical and should be taken seriously. So immediately after creation I edited the inbound rule to allow 3389 only from my own Public IP.
Find that out with whatsmyip for example – If your ISP changes your IP, just edit that rule again with your new IP – a small sacrifice to not be port scanned into oblivion.
Auto-shutdown on. A small budget-control which is easy implemented through the portal. Set a daily shutdown time and pick your timezone. I set mine for the evening after I usually go to bed. This simple fix prevents surprise bills.
Important to know that Disk costs are still running, only the VM running cost is reduced.
/phase 2 – promote to a domain controller
I RDP’d in and did the promotion through the GUI, because for me it was important to really see what needed to be done, rather than just let a script do it for me. After this I would let a script run for me instead – saving time by a lot.
In the Server Manager: Add Roles and Features -> Install Active Directory Domain Services

After that the yellow notification flag at the top offers Promote this server to a domain controller. I choose Add a new forest and gave it a domain name.
And here is my first confession of the week, the on that came back to bite me later. I named the domain lab.loc.
If you know, you know. I’ll get to why that was a mistake. At the time it felt harmless .loc looks tidy and “lab-like” but hold that thought.
The rest of the promotion wizard:
- Functional level: Windows Server 2016. 2016 is the highest forest functional level that exists, might look wrong going through the guides at first glance. There is no 2019/2022/2025 level.
- DSRM password. The Directory Services Restore Mode recovery password. Set it, save it, move on.
- DNS delegation warning: you’ll get a warning that a delegation for DNS server can’t be created. In a standalone lab this is completely normal – Just Proceed.
- Paths, leave the AD database, logs etc. on the C: drive. Never put them on the D: drive. In an Azure VM, the D: is an ephemeral disk, that gets wiped on deallocation (reboot/shutdown etc.). So leave the default options and move on.
After those steps, the server needs to reboot. When it comes back online you log into it as a domain account for the first time. The fake on-prem forest exists now.
/phase 3 – the dns twist
After reboot I checked the DC’s network config and saw its DNS servers listed as:
DNS Servers . . . . . . . . . . . : ::1
127.0.0.1
My first thought was why it didn’t show its own private IP adress, and that something might have been broken. But this is actually correct, and it’s worth understanding why, because it’s a great little illustration of how AD and DNS intertwine.
When you promote a server that’s also a DNS server, the promotion repoints the machines own DNS client at loopback (127.0.0.1 and ::1). This just means that this box is the DNS Server now, so it should resolve through itself. So 127.0.0.1, ::1 and 10.1.0.5 (the private IP) is effectively the same room with three different doors.
Besides that, there are two pieces of DNS plumbing that do need to be done though:
- A forwarder, so the DC can resolve the internet. Out of the box my DC could resolve lab.loc but not microsoft.com (theoretically) – and EntraID Connect very much needs to reach the internet.
In DNS Manager, I checked the forwarder, which was already pointing at 168.63.129.16, which is Azure’s magic platform DNS address. Now I have confirmed that the DC answers for its own domain and forwards everything else out to the internet.

- 2. Point the VNet’s DNS at the DC. In the portal, on my hub vnet, I set the custom DNS server to
10.1.0.5. This is the step i quietly mentioned in phase 1. It means every VM I ever add to this VNnet automatically uses the DC for DNS. And since you can only join a domain if you can resolve that domains DNS records, this is precisley what will let the future VMs find and join lab.loc with zero extra configurations.
(Already running VM’s wont pick up the change unless you reboot those)
/phase 4 – EntraID tenant
I have used my own EntraID tenant for my testings, but it is highly recommended to use a separate EntraID tenant – cutoff from your prod environment. Create a new EntraID can be done with very little work and requires almost no technical knowledge.
A side note if you’ve or are about to create a new Tenant, wait 10-30 minutes after creating a fresh tenant before installing Entra Connect. A brand-new tenant takes a little while to fully initialize. -> Make a coffee for this period.
/phase 5 – my .loc problem
I kicked off the Entra Connect Installer, chose Customize (always pick Customize over Express for lab – you effectively see and control more), and start clicking through. Then this warning appeared:
lab.loc is not a routable domain. It is recommended to use custom settings to configure user sign-in options.
This just means that the lab.loc is a non-routable suffix. It can never ever exist on the public internet, which means I could never verify it in EntraID. That matters because, by default, a user’s on-prem login name is [email protected]. Since Entra can’t verify lab.loc, it won’t accept those names – instead it would sync every user as [email protected]. Functional but ugly, and not how real hybrid setup looks.
The fix has two points:
- Verify a real domain. I happen to own casawulf.xyz for labbing purposes, so I added it as a custom domain in the EntraID admin center and completed the verification. (proving your ownership by adding a TXT record in my DNS registrar).
Not Entra trusts that domain. - Teach AD to use it. A verified Domain in EntraID is no good if my AD users still carry @lab.loc. So on the DC, in Active Directory Domains and Trusts -> Properties -> UPN Suffix, I added casawulf.xyz as an available suffix. Then in Active Directory Users and Computers, I edited and created test user accounts with @casawulf.xyz.

The lesson learned here is: name your forest with a routable domain from the very start – a subdomain of something you own, like in my case corp.casawulf.xyz. It would have saved me this little detour.
/phase 6 – the credentials error
Back in the Entra Connect wizard, on the Connect Directories step, I entered my forest and clicked Add Directory to give it AD credentials. It got rejected with the message:
The username or password is incorrect. Using credentials with a fully qualified domain may help to resolve this issue.
I’d typed my password correctly, so the first part couldn’t be true. The second part therefore must’ve been the culprit. Entra Connect wnats the account in fully-quallified form, not a bare username. Typing Administrator fails, typing LAB\Administrator or [email protected] works. The account also needs to be an Enterprise Admin.
So with my LAB\Administrator, the directory was accepted and the wizard moved on.
/phase 7 – remaining wizard choices
There are two more pages that look like they need a decision but mostly dont:
The UPN suffix/sign in page now showed casawulf.xyz as verified (green), with lab.loc still flagged as not verified. And that’s fine. Users carrying @casawulf.xyz sinc with that real name, any leftover @lab.loc just fallback to the .onmicrosoft.com name. So I left the UPN attribute on the default userPrincipalName and continued.
The “uniquely identifying your users” page sounds intimidating, but the defaults are right for a single-forest lab. “Users are represented only once across all directories” is true – I have only one forest anyway. Continue with the wizard.
I made sure “Start the synchronization process when configuration completes” was ticket, and hit Install.
/the payoff
A minute or two later and I opened my Entra Admin Center -> Users, and there they were. My on-prem test AD accounts, now present in the cloud with @casawulf.xyz names. On the “On-premises sync enabled” tab you can see which users were synced from on-prem:

Hybrid identity working, built entirely inside Azure, for the price of a cost-effective VM I deallocate every night automatically.
/wach out for the bill
The running cost of this is mainly the Disk used by the VM and its Public IP address. Deallocating the VM only reduces the cost by a little bit – the disk and public ip is still running and therefore generates costs.
Delete the whole resource group the DC is staning in after you have created and tested everything you wanted to. A good point would be to automate this the next time so you don’t have to click through everything – taking much more time than IaC and Code – we might do that next.
/what to do differently, and whats next
If I rebuilt this tomorrow, the only real change is the name of the forest, make it routeable from day one (corp.casawulf.xyz) so the .loc UPN detour does not happen.
Everything else – VM, locked RDP, DC-as-DNS with a forwarder etc. – I’d like to automate that with IaC and Scripts so I could just spin it up and delete it with a single command.
Next week I want to take this further, spin up a Windows Client VM in the same Vnet, join it to lab.loc and then configure device hybrid join so the machine registers in both my on-prem AD and my Entra tenant. That’s where I suppose it gets genuinely interesting. I suspect that I will walk into a lot more mistakes there of which I can learn a lot from.

