Hi everyone,
Welcome to another deploying Azure resources with Terraform blogpost. As you all know the support for Server 2012 and Server 2012 R2 is stopping. Because of this a lot of companies need to deploy new domain controllers. In this blogpost I’ll show you the deployment of 2 domain controllers in West Europe with the best practices from Microsoft.
Prerequisites
- Log Analytics Workspace for diagnostic settings
- storage account for boot diagnostics
- Identity subnet in the hub virtual network with 3 ip’s
- Azure Key Vault with local admin secret
Before we can start deploying the domain controllers we need to add some data sources for the prerequisites.
data "azurerm_log_analytics_workspace" "law" {
name = "law-hub-${var.prefix}-01"
resource_group_name = "rg-hub-${var.prefix}-management-01"
}
data "azurerm_virtual_network" "hub" {
provider = azurerm.hub
name = "vnet-hub-${var.prefix}-we-01"
resource_group_name = "rg-hub-${var.prefix}-networking-01"
}
data "azurerm_subnet" "identity" {
provider = azurerm.hub
name = "snet-hub-${var.prefix}-identity-01"
virtual_network_name = data.azurerm_virtual_network.hub.name
resource_group_name = data.azurerm_virtual_network.hub.resource_group_name
}
data "azurerm_storage_account" "bootdiagdc" {
provider = azurerm.hub
name = "sthub${var.prefix}bootdiag01"
resource_group_name = "rg-hub-${var.prefix}-storage-01"
}
data "azurerm_resource_group" "rg-dc" {
name = "rg-hub-${var.prefix}-dc-01"
}
data "azurerm_key_vault" "kv-hub" {
name = "kv-hub-${var.prefix}-80"
resource_group_name = "rg-hub-${var.prefix}-management-01"
}
data "azurerm_key_vault_secret" "loc-admin" {
name = "loc-admin"
key_vault_id = data.azurerm_key_vault.kv-hub.id
}
Now that we have the prerequisites it’s time to start with the code for the virtual machines.
I want to highlight a couple of pieces of code for these domain controllers.
- vm is added to an availability set for redundancy
- System assigned identity is added for security
- Secure boot and vtpm are enabled
- Provisioning of the vm agent
resource "azurerm_windows_virtual_machine" "dc1" {
provider = azurerm.hub
name = "vm-${var.prefix}-dc-01"
resource_group_name = data.azurerm_resource_group.rg-dc.name
location = data.azurerm_resource_group.rg-dc.location
network_interface_ids = [azurerm_network_interface.nic-dc-01.id]
size = "Standard_F2s_v2"
admin_username = data.azurerm_key_vault_secret.loc-admin.name
admin_password = data.azurerm_key_vault_secret.loc-admin.value
patch_mode = "Manual"
identity {
type = "SystemAssigned"
}
secure_boot_enabled = true
vtpm_enabled = true
provision_vm_agent = true
os_disk {
name = "c-vm-${var.prefix}-dc-01"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
disk_size_gb = 64
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-Datacenter-smalldisk"
version = "latest"
}
tags = {
"Critical" = "Yes"
"Solution" = "Domain Controller"
"Costcenter" = "IT"
"Environment" = "Hub"
}
availability_set_id = azurerm_availability_set.avs-dc.id
boot_diagnostics {
storage_account_uri = data.azurerm_storage_account.bootdiagdc.primary_blob_endpoint
}
}
It is recommended by Microsoft not to put the ntds on the c drive of your domain controller. For this reason I add an extra disk and turn off the caching on the disk.
resource "azurerm_managed_disk" "dc1-datadisk" {
name = "f-vm-${var.prefix}-dc-01"
resource_group_name = azurerm_windows_virtual_machine.dc1.resource_group_name
location = data.azurerm_resource_group.rg-dc.location
storage_account_type = "Premium_LRS"
disk_size_gb = 32
create_option = "Empty"
}
resource "azurerm_virtual_machine_data_disk_attachment" "dc1-datadisk-attach" {
managed_disk_id = azurerm_managed_disk.dc1-datadisk.id
virtual_machine_id = azurerm_windows_virtual_machine.dc1.id
lun = "1"
caching = "None"
}
The last resource that we need is the network interface. when deploying the nic the allocation type will be dynamic. Don’t forget to change it to static.
The allocation type of the nic won’t be visible when promoting the machine to domain controller.
resource "azurerm_network_interface" "nic-dc-01" {
provider = azurerm.hub
name = "nic-01-vm-${var.prefix}-dc-01"
resource_group_name = data.azurerm_resource_group.rg-dc.name
location = var.location
ip_configuration {
name = "sip-vm-${var.prefix}-dc-01"
subnet_id = data.azurerm_subnet.identity.id
private_ip_address_allocation = "Dynamic"
}
tags = {
"Critical" = "Yes"
"Solution" = "Network interface"
"Costcenter" = "IT"
"Environment" = "Hub"
}
}
resource "azurerm_monitor_diagnostic_setting" "diag-nic1" {
name = "diag-nic"
target_resource_id = azurerm_network_interface.nic-dc-01.id
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.law.id
metric {
category = "AllMetrics"
retention_policy {
enabled = true
}
}
}
After the deployment you can choose to enable Azure Disk Encryption on the domain controllers. I already a blog post about this. You can read it here.
If you want to use the code, you can find it on my Github here.
I hope this blog post will help you to deploy domain controllers in Azure. If you have any questions about this, feel free to contact me.