Deploying and Configuring a Hybrid Identity Lab Using Bicep - Part 1: Active Directory Setup and Sync
Introduction Setting up a hybrid identity lab is a fantastic way to dive into the world of modern identity and access management. Since there's so much to cover in this exciting field, it’s best to break it down into smaller, bite-sized chunks. That way, you can tackle each piece one at a time and have fun while building your skills without feeling overwhelmed! Part 1: Configuring Active Directory and Entra Connect Sync In this first part, we’ll set up on-premises Active Directory (AD) and configure Entra Connect (formerly AAD Connect) to sync user identities with Entra ID. This critical step enables hybrid identity, allowing seamless access to on-premises and cloud resources with a single identity. Objectives of Part 1: Set up an On-Premises Active Directory Domain Services (AD DS) environment. Install and configure Microsoft Entra Connect Sync. Sync users from on-premises AD to Entra ID. Verify the sync between on-premises AD and Entra ID. We’ll cover: Deploying resources using a Bicep template. Syncing on-prem users to Entra ID with Entra Connect. By the end of this lab, you’ll have a functional hybrid identity setup to experiment with. Prerequisites Before starting, ensure you have: Azure Subscription: Active and with P1 license. You can do this lab practice with Free subscription as well, just with limitations. Free license does not allow you to create custom domain for example. Setup custom domain in your tenant: https://learn.microsoft.com/en-us/entra/fundamentals/add-custom-domain Cloud user with Global Admin rights Get the Bicep files from here: https://github.com/neontiger12/EntraConnect Install Visual Studio Code: use VS Code to modify the bicep files. Lab setup All the resources will be deployed in the West Europe region. The virtual network details: VNet Name: VirtualNetwork01 IP Address Space for VNet: 10.1.0.0/16 **Subnet Name: **Subnet01 Subnet IP Address Range: 10.1.1.0/24 Domain Controller - Server Virtual machine name: DC1 Static private address: 10.1.1.5 What is Bicep and Why Use It? Bicep is a domain-specific language (DSL) for deploying Azure resources. It simplifies the process of defining infrastructure as code (IaC), making templates easier to read, write, and maintain compared to traditional JSON ARM templates. Here’s why we’re using Bicep in this lab: It allows for declarative infrastructure: You specify what you want, and Azure takes care about the how to do it. It provides a modular approach: Resources like the VNet and server can be managed independently. It’s easier to write and manage: Bicep is more human-readable, which reduces errors and accelerates deployment. For those new to Bicep, stay tuned! I’ll explain the templates step-by-step in a future post to help you build and customize your own deployments. A quick run through the files: The configurations for the client and server are split into separate modules to make the Bicep file more organized and readable: Network Module: Manages networking resources like the VNet and subnets. Server Module: Handles server settings like VM size, OS, and network interfaces. This modular approach improves readability, reusability, and simplifies management. The main Bicep file acts as the central point that ties everything together. It references the network and server modules, passing in the required parameters and ensuring all resources are deployed in a coordinated way. This keeps the structure clean and easy to maintain. 1 - Setup the environment for the Bicep template Install Azure CLI: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli Login to your Azure account: az login https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactively Install the bicep extension in Visual Studio Code (if you would like to modify the Bicep files) We are using the terminal of the VS Code for easier access. Make sure you are running the commands from the directory where you store the bicep files. 2 - Deploying the Virtual Network This guide explains how to deploy a Windows Server hosting Active Directory Domain Services (AD DS) using Bicep. We'll separate the deployment into two resource groups: Resource Group for the Virtual Network (VNet): Shared between the server and client. Resource Group for the Server: Hosts the Windows Server for AD DS. The first step is to deploy the VNet, which will connect the AD server and the client machine. We need to create a separate resource group for this. For example the name of the vnet is "Vnet", the location is Westeurope. az group create --name Vnet --location westeurope Check the deployment result.You should see 'Succeeded'. Now, we are deploying the Vnet resource: az deployment group create --resource-group VNet --template-file vnet.bicep After the deployment check the provisioning state, it should be "Succeeded" Now th
Introduction
Setting up a hybrid identity lab is a fantastic way to dive into the world of modern identity and access management. Since there's so much to cover in this exciting field, it’s best to break it down into smaller, bite-sized chunks. That way, you can tackle each piece one at a time and have fun while building your skills without feeling overwhelmed!
Part 1: Configuring Active Directory and Entra Connect Sync
In this first part, we’ll set up on-premises Active Directory (AD) and configure Entra Connect (formerly AAD Connect) to sync user identities with Entra ID. This critical step enables hybrid identity, allowing seamless access to on-premises and cloud resources with a single identity.
Objectives of Part 1:
- Set up an On-Premises Active Directory Domain Services (AD DS) environment.
- Install and configure Microsoft Entra Connect Sync.
- Sync users from on-premises AD to Entra ID.
- Verify the sync between on-premises AD and Entra ID.
We’ll cover:
- Deploying resources using a Bicep template.
- Syncing on-prem users to Entra ID with Entra Connect.
By the end of this lab, you’ll have a functional hybrid identity setup to experiment with.
Prerequisites
Before starting, ensure you have:
Azure Subscription: Active and with P1 license.
You can do this lab practice with Free subscription as well, just with limitations. Free license does not allow you to create custom domain for example.
Setup custom domain in your tenant:
https://learn.microsoft.com/en-us/entra/fundamentals/add-custom-domain
Cloud user with Global Admin rights
Get the Bicep files from here: https://github.com/neontiger12/EntraConnect
Install Visual Studio Code: use VS Code to modify the bicep files.
Lab setup
All the resources will be deployed in the West Europe region.
The virtual network details:
- VNet Name: VirtualNetwork01
- IP Address Space for VNet: 10.1.0.0/16
- **Subnet Name: **Subnet01
- Subnet IP Address Range: 10.1.1.0/24
Domain Controller - Server
- Virtual machine name: DC1
- Static private address: 10.1.1.5
What is Bicep and Why Use It?
Bicep is a domain-specific language (DSL) for deploying Azure resources. It simplifies the process of defining infrastructure as code (IaC), making templates easier to read, write, and maintain compared to traditional JSON ARM templates.
Here’s why we’re using Bicep in this lab:
- It allows for declarative infrastructure: You specify what you want, and Azure takes care about the how to do it.
- It provides a modular approach: Resources like the VNet and server can be managed independently.
- It’s easier to write and manage: Bicep is more human-readable, which reduces errors and accelerates deployment.
For those new to Bicep, stay tuned! I’ll explain the templates step-by-step in a future post to help you build and customize your own deployments.
A quick run through the files:
The configurations for the client and server are split into separate modules to make the Bicep file more organized and readable:
Network Module: Manages networking resources like the VNet and subnets.
Server Module: Handles server settings like VM size, OS, and network interfaces.
This modular approach improves readability, reusability, and simplifies management.
The main Bicep file acts as the central point that ties everything together. It references the network and server modules, passing in the required parameters and ensuring all resources are deployed in a coordinated way. This keeps the structure clean and easy to maintain.
1 - Setup the environment for the Bicep template
Install Azure CLI: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli
Login to your Azure account:
az login
https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli-interactivelyInstall the bicep extension in Visual Studio Code (if you would like to modify the Bicep files)
We are using the terminal of the VS Code for easier access. Make sure you are running the commands from the directory where you store the bicep files.
2 - Deploying the Virtual Network
This guide explains how to deploy a Windows Server hosting Active Directory Domain Services (AD DS) using Bicep. We'll separate the deployment into two resource groups:
- Resource Group for the Virtual Network (VNet): Shared between the server and client.
- Resource Group for the Server: Hosts the Windows Server for AD DS.
The first step is to deploy the VNet, which will connect the AD server and the client machine.
We need to create a separate resource group for this.
For example the name of the vnet is "Vnet", the location is Westeurope.
az group create --name Vnet --location westeurope
Check the deployment result.You should see 'Succeeded'.
Now, we are deploying the Vnet resource:
az deployment group create --resource-group VNet --template-file vnet.bicep
After the deployment check the provisioning state, it should be "Succeeded"
Now that the network is set up, we’re ready to deploy the Domain Controller (DC)!
3 - Deploy the Server for the Domain Controller
Create the resource group first:
az group create --name DC_RG --location westeurope
After the successfully creating the resource group lets deploy the server!
az deployment group create --resource-group DC_RG --template-file main-server.bicep
You will be asked to provide the admin username and password:
After a couple of minutes the deployment should be ready.
provisioningState": "Succeeded"
Go to the Azure portal check the VM you just created and click Connect:
Download the RDP file and open it to remotely connect.
Since we enabled port 3389 you should not face any issue connecting.
We are ready to setup the Domain Controller and the DNS service on the server.
4 - Configure the DC and DNS service
Open the ADDS.ps1 with PowerShell ISE and Replace placeholder values yourdomain.local, yourdomain, and P@ssw0rd! representing your environment:
Run the script. The server will restart once the installation finishes.
Reconnect and check the Server Manager. You should see the ADDS and the DNS configured.
Now it is time to create users!
Modify the placeholders for user prefix, domain and password to match your environment.
After running the script check the created new users:
If you check the domain you see that we used a non-routable domain: neontiger.local for this example. This is good for internal use, however we need to ensure we can synchronise our newly created users to Entra ID.
For synchronisation, Entra ID requires that at least one domain is routable and verified in your Azure tenant.
Entra ID uses User Principal Names (UPNs) to identify users.
If your UPN suffix is @neontiger.local, Entra ID will not accept it because it's non-routable.
A routable, verified domain (like neontiger12.com in this example) is required for UPNs to sync properly with Entra ID.
Add your custom domain name to Active Directory Domains and Trust:
- right click on Active Directory Domains and Trust and click Properties
Don't forget to click Apply and then OK.
If you check your user's property again you should see the new domain available:
Let's fix the UPN for the users!
Microsoft's IdFix tool helps you to prepare your AD for the synchronisation. It identifies and fix issues, like the non-routable UPNs.
Download and install the tool.
IDfix
https://github.com/microsoft/idfix/tree/master/MSIs
Run the Query.
The result will show the issue with the UPN:
Open the UPN_update.ps1 with PowerShell ISE and replace the relevant parameters to represent your current local and the new routable domain.
Run the script to update the UPN of the users.
Run the IdFix query again to confirm that the script has resolved the issue.
Now the Cloudup users should disappeared from the list.
There is one tiny problem left with my admin user: the DisplayName attribute is empty. Fix it by adding some value to that:
Users are ready, now let's do the connect to Entra ID!
5 - Connect to Entra ID
Fix the TLS 1.2
Entra ID Connect requires TLS 1.2. You can enable it on your server by running the following script (tls.ps1) from:
https://github.com/neontiger12/EntraConnect/tree/main/powershell-scripts
Download and install the Entra Connect Sync:
https://www.microsoft.com/en-us/download/details.aspx?id=47594
Accept the terms and conditions and click Continue.
Choose Customise, leave the next page as default and click Install.
Choosing a Customized Entra Connect setup allows you to tailor synchronization options to your specific needs, such as filtering which organizational units (OUs) or attributes to sync, or enabling password writeback.
User Sign-In
The Sign On method is Password Hash Syncronization.
Click Next.
Connect to Microsoft Entra ID
Use your Global Admin user to connect.
You might face this issue with the sign-in:
Add the required sites to the Trusted sites.
Still after adding all of those site you can see this error message:
To fix this open Internet Options from the Control Panel: Network and Internet » Internet Options. Lower the security level of the Trusted sites.
Note: Avoid simply searching for "Internet Options" to fix this issue, as you may encounter permission-related restrictions.
Try to sign in again, this time it should work.
Connect your directories
Click Add Directory and configure a new domain admin:
When it is ready, click Next.
*Microsoft Entra Sign-in configuration
*
Tick the box next to Continue without matching all UPN suffixes to verified domain.
It's okay to continue setting up Entra Connect without matching all UPN suffixes to a verified domain, as the local domain in Active Directory will still function internally, and this setup is sufficient for our lab environment.
Domain and OU filtering
For this lab we sync all domains and OUs. Click Next.
Uniquely identify your users
Leave everything as default. We let Azure to use the mS-DS-Consistency GUID as a sourceAnchor.
The mS-DS-Conistency GUID is an attribute that uniquely identifies a user both in Active Directory and in Entra. Often leveraged as the sourceAnchor. It ensures that even if a user changes their name, the attribute remains the same, preventing the creation of a new user in Entra ID; instead, it simply updates the user's details (e.g., last name)
The sourceAnchor (also called immutableId) is an attribute that uniquely identifies an object in both on-premises Active Directory and Microsoft Entra ID. It is a Base64 encoded representation of the mS-DS-Consistency GUID.
Click Next.
Filter users and devices
Leave as default. Filtering is out of scope for this lab.
Click Next.
Optional features
Enable Password writeback as we will need this for the Self service password reset.
Ready to configure
Install.
Configuring may take a while. Maybe it is time to grab a cup of coffee :).
Once the setup is complete, you should see the 'Configuration Complete' window. The synchronisation started, wait a few minutes and check the newly added users in Entra ID.
The On-premise sync enabled is set to yes for these users.
If you check the properties for the user you can see all the attributes that were sync from AD.
You cannot change these because from Entra's prospective the on-prem AD is the source of truth.
The usage location is a good example for an attribute that you can set in Entra. This attribute can effect licensing options.
Look at the On-premises immutable ID for CloudUser1:
Now check this attribute in the Active Directory Users and Computers.
To see this option in properties we need to enable the advanced features:
- Enable Advanced Features under the View menu.
- Right-click the user account and select Properties.
- Go to the Attribute Editor tab.
- Find mS-DS-ConsistencyGUID in the list of attributes.
You might face the same issue as me, the mS-DS-ConsistencyGUID attribute is empty.
Let's fix that by initiating a sync cycle.
There is a handy PowerShell command to do it.
First install the ADSyncTools:
Install-Module -Name ADSyncTools
Reopen PowerShell ISE.
Import the module:
Import-Module -Name ADSync
Initiate a sync cycle:
Start-ADSyncSyncCycle -PolicyType Delta
The result we expecting is "Success".
Delta sync handels only changes made since the last sync to keep Entra ID updated efficiently. Initial sync, on the other hand, is the first sync that brings in all objects from on-premises AD to Entra ID. Delta is faster and incremental, while Initial is comprehensive and sets the baseline.
Now, check the attribute again in Active Directory to see if it's populated.
Now it is there however you still not sure if they are the same?
I can understand why you questioning that :).
Open the convert.ps1 script in PowerShell ISE and edit the parameters according the values your user have.
Now run the script and check the result.
Remember, I mentioned in the Uniquely identify section of the Entra Connect setup: the On-premise immutable ID is the Base64 encoded representation of the mS-DS-ConsistencyGUID attribute.
If you decode that you can confirm that those two values are the same! :)
Other way to check the sourceAnchor
You can also check these attributes with the Syncronization Service Manager.
This tool allows you to monitor and manage syncronization, provides detailed logs and information about syncronization cycle. Great to have this for troubleshooting!
Don't get overwhelmed by all those information you see.
Explaining the details about how Entra Connect Sync works deserves a post of their own.
For now it is enough if you understand that the Entra Connect consist of two Connector space: one for your on-prem AD, and one for the Entra ID.
The **connector space **holds a copy of each object and its attributes from a connected data source, helping Entra Connect track changes for proper synchronization.
The Metaverse in Entra Connect is a central database that combines and stores information from all connected data sources, creating a unified view of objects for synchronization with Entra ID.
With that in mind go to the Metaverse Search and click Search on the right hand side.
Right click on CloudUser 1 and click Properties.
The attributes displayed are those relevant to the Metaverse for that specific user. The sourceAnchor (also known as Immutable ID) is used as the unique identifier in Entra ID, while the mS-DS-ConsistencyGUID serves as the unique identifier for the identity in Active Directory.
To check the attributes applicable for the Active Directory go to the Connectors tab and select the connector that is representing your AD. Click properties.
Now you can see the mS-DS-ConsistencyGUID.
Vigilant readers might discover that the mS-DS-ConsistencyGUID is the same as the objectGUID.
This is because the mS-DS-ConsistencyGUID is copied from the objectGUID when Entra Connect first replicates the user.
The objectGUID in Active Directory changes only if the object is deleted and then re-created or if it is moved to a different AD forest. To maintain the link between Active Directory and Entra ID, we use an immutable ID that consistently represents the identity, even if other attributes change.
In the Syncronization Service Manager you can see the status of the import/export shown as "success".
Feel free to explore the Service Manager a bit more if you have time—it’s a great tool for understanding the sync process.
In the next part we will cover Entra Connect Health to further monitor our synchronization process.
Further study
For a more in-depth understanding of Entra Connect, check out this YouTube video by John Savill's Technical Training:
What is the link between Azure AD (AAD) and AD users?. It provides an excellent walkthrough and complements the concepts covered here.