'How to configure the VMs in two different zones using Availability Sets and install the Active Directory Domain services
I’m trying to create the two windows virtual machines in two different zones using the following terraform code:
## Import exisiting resource group
## Use this data source to access information about an existing Resource Group
data "azurerm_resource_group" "resource_group" {
name = var.existing_rg_name
}
## Import exisiting virtual network
## Use this data source to access information about an existing Virtual Network.
data "azurerm_virtual_network" "virtual_network" {
resource_group_name = var.existing_rg_name
name = var.existing_vnet_name
}
## Import exisiting subnet with in a virtual network
## Use this data source to access information about an existing Subnet within a Virtual Network.
data "azurerm_subnet" "subnet" {
name = var.existing_subnet_name
virtual_network_name = var.existing_vnet_name
resource_group_name = var.existing_rg_name
}
## Configure Availiablility set
resource "azurerm_availability_set" "availability_set" {
name = var.avset_name
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_resource_group.resource_group.location
platform_fault_domain_count = 2
platform_update_domain_count = 2
managed = true
}
## Create Public IP
resource "azurerm_public_ip" "public_ip" {
name = var.pip_name
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_resource_group.resource_group.location
allocation_method = "Dynamic"
}
## Create network interface for VM
resource "azurerm_network_interface" "vm_nic" {
name = var.nic_name
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_resource_group.resource_group.location
ip_configuration {
name = "internal"
subnet_id = data.azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.public_ip.id
}
}
## Create Windows Virtual Machine
resource "azurerm_windows_virtual_machine" "virtual_machine" {
name = var.vm_name
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_resource_group.resource_group.location
size = var.vm_size
admin_username = var.vm_username
admin_password = var.vm_password
network_interface_ids = [
azurerm_network_interface.vm_nic.id
]
availability_set_id = azurerm_availability_set.availability_set.id
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-Datacenter"
version = "latest"
}
depends_on = [
azurerm_network_interface.vm_nic
]
}
I want to configure the VMs in two different zones using Availability Sets and install the Active Directory Domain services using terraform.
Solution 1:[1]
You can use something like below to deploy 2 VM's and Create a new active directory forest in one and in other you can just add it to domain and promote both as Domain Controllers:
Availability Set:
Main.tf:
provider "azurerm" {
features{}
}
## Import exisiting resource group
## Use this data source to access information about an existing Resource Group
data "azurerm_resource_group" "resource_group" {
name = "ansumantest"
}
## Import exisiting virtual network
## Use this data source to access information about an existing Virtual Network.
data "azurerm_virtual_network" "virtual_network" {
resource_group_name = data.azurerm_resource_group.resource_group.name
name = "ansuman-vnet"
}
## Import exisiting subnet with in a virtual network
## Use this data source to access information about an existing Subnet within a Virtual Network.
data "azurerm_subnet" "subnet" {
name = "default"
virtual_network_name = data.azurerm_virtual_network.virtual_network.name
resource_group_name = data.azurerm_resource_group.resource_group.name
}
## Configure Availiablility set
resource "azurerm_availability_set" "availability_set" {
name = "ansuman-avset"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
platform_fault_domain_count = 2
platform_update_domain_count = 2
managed = true
}
## Create 2 Public IP
resource "azurerm_public_ip" "public_ip" {
count = 2
name = "ansuman-pip-${count.index}"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
allocation_method = "Dynamic"
}
#Static Private address to be used by the server each
variable "PrivateIP" {
default=["10.0.0.5","10.0.0.6"]
}
## Create network interface for VM with adding the static Private IP's in the DNS server list
resource "azurerm_network_interface" "vm_nic" {
count = 2
name = "vm-${count.index}-nic"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
dns_servers = var.PrivateIP
ip_configuration {
name = "internal"
subnet_id = data.azurerm_subnet.subnet.id
private_ip_address_allocation = "Static"
private_ip_address = var.PrivateIP[count.index]
public_ip_address_id = azurerm_public_ip.public_ip[count.index].id
}
}
## Create 2 Windows Virtual Machine
resource "azurerm_windows_virtual_machine" "virtual_machine" {
count = 2
name = "AZDC-${count.index}"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
size = "Standard_F8s_v2"
admin_username = "ansuman"
admin_password = "Password@1234"
network_interface_ids = [
azurerm_network_interface.vm_nic[count.index].id
]
availability_set_id = azurerm_availability_set.availability_set.id
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-Datacenter"
version = "latest"
}
depends_on = [
azurerm_network_interface.vm_nic
]
}
#Powershell commands to run the ADDS in the VM's
locals {
import_command = "Import-Module ADDSDeployment"
password_command = "$password = ConvertTo-SecureString ${var.admin_password} -AsPlainText -Force"
credentials_command = "$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist ${var.domainAdminUsername},$password"
install_ad_command = "Add-WindowsFeature -name ad-domain-services,dns -IncludeManagementTools"
configure_ad_command = "Install-ADDSForest -CreateDnsDelegation:$false -DomainMode Win2012R2 -DomainName ${var.active_directory_domain} -DomainNetbiosName ${var.active_directory_netbios_name} -ForestMode Win2012R2 -InstallDns:$true -SafeModeAdministratorPassword $password -Force:$true"
promote_adds_command = "Install-ADDSDomainController -DomainName ${var.active_directory_domain} -InstallDns -Credential $credentials -SafeModeAdministratorPassword $password -Force:$true"
shutdown_command = "shutdown -r -t 10"
exit_code_hack = "exit 0"
powershell_command = "${local.import_command}; ${local.password_command}; ${local.install_ad_command}; ${local.configure_ad_command}; ${local.shutdown_command}; ${local.exit_code_hack}"
powershell_promote_command = "${local.password_command};${local.credentials_command}; ${local.install_ad_command}; ${local.promote_adds_command}; ${local.shutdown_command}; ${local.exit_code_hack}"
}
#creating a forest and promoting the Primary server as a DC
resource "azurerm_virtual_machine_extension" "create-active-directory-forest" {
name = "create-active-directory-forest"
virtual_machine_id = azurerm_windows_virtual_machine.virtual_machine[0].id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -Command \"${local.powershell_command}\""
}
SETTINGS
}
# Adding Secondary server to the Domain and promoting it as DC
resource "azurerm_virtual_machine_extension" "promote-to-domain-controller" {
name = "promote-to-domain-controller"
virtual_machine_id = azurerm_windows_virtual_machine.virtual_machine[1].id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -Command \"${local.powershell_promote_command}\""
}
SETTINGS
depends_on = [
azurerm_virtual_machine_extension.create-active-directory-forest
]
}
Variable.tf:
variable "active_directory_domain" {
description = "The name of the Active Directory domain, for example `consoto.local`"
default = "contoso.local"
}
variable "admin_password" {
description = "The password associated with the local administrator account on the virtual machine"
default = "Password@1234"
}
variable "active_directory_netbios_name" {
description = "The netbios name of the Active Directory domain, for example `consoto`"
default = "Contoso"
}
variable "domainAdminUsername" {
description = "The local administrator account on the Domain"
default = "[email protected]"
}
Output:
Availability Zone:
main.tf
provider "azurerm" {
features{}
}
## Import exisiting resource group
## Use this data source to access information about an existing Resource Group
data "azurerm_resource_group" "resource_group" {
name = "ansumantest"
}
## Import exisiting virtual network
## Use this data source to access information about an existing Virtual Network.
data "azurerm_virtual_network" "virtual_network" {
resource_group_name = data.azurerm_resource_group.resource_group.name
name = "ansuman-vnet"
}
## Import exisiting subnet with in a virtual network
## Use this data source to access information about an existing Subnet within a Virtual Network.
data "azurerm_subnet" "subnet" {
name = "default"
virtual_network_name = data.azurerm_virtual_network.virtual_network.name
resource_group_name = data.azurerm_resource_group.resource_group.name
}
##availabilty zones
variable "Zone" {
default=["1","2"]
}
resource "azurerm_network_security_group" "example" {
name = "ansuman-nsg"
location = data.azurerm_virtual_network.virtual_network.location
resource_group_name = data.azurerm_resource_group.resource_group.name
security_rule {
name = "test123"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_subnet_network_security_group_association" "example" {
subnet_id = data.azurerm_subnet.subnet.id
network_security_group_id = azurerm_network_security_group.example.id
}
## Create 2 Public IP
resource "azurerm_public_ip" "public_ip" {
count = 2
name = "ansuman-pip-${count.index}"
sku = "Standard"
availability_zone = var.Zone[count.index]
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
allocation_method = "Static"
}
#Static Private address to be used by the server each
variable "PrivateIP" {
default=["10.0.0.5","10.0.0.6"]
}
## Create network interface for VM with adding the static Private IP's in the DNS server list
resource "azurerm_network_interface" "vm_nic" {
count = 2
name = "vm-${count.index}-nic"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
dns_servers = var.PrivateIP
ip_configuration {
name = "internal"
subnet_id = data.azurerm_subnet.subnet.id
private_ip_address_allocation = "Static"
private_ip_address = var.PrivateIP[count.index]
public_ip_address_id = azurerm_public_ip.public_ip[count.index].id
}
}
## Create 2 Windows Virtual Machine
resource "azurerm_windows_virtual_machine" "virtual_machine" {
count = 2
name = "AZDC-${count.index}"
resource_group_name = data.azurerm_resource_group.resource_group.name
location = data.azurerm_virtual_network.virtual_network.location
size = "Standard_F8s_v2"
admin_username = "ansuman"
admin_password = "Password@1234"
zone = var.Zone[count.index]
network_interface_ids = [
azurerm_network_interface.vm_nic[count.index].id
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-Datacenter"
version = "latest"
}
depends_on = [
azurerm_network_interface.vm_nic
]
}
#Powershell commands to run the ADDS in the VM's
locals {
import_command = "Import-Module ADDSDeployment"
password_command = "$password = ConvertTo-SecureString ${var.admin_password} -AsPlainText -Force"
credentials_command = "$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist ${var.domainAdminUsername},$password"
install_ad_command = "Add-WindowsFeature -name ad-domain-services,dns -IncludeManagementTools"
configure_ad_command = "Install-ADDSForest -CreateDnsDelegation:$false -DomainMode Win2012R2 -DomainName ${var.active_directory_domain} -DomainNetbiosName ${var.active_directory_netbios_name} -ForestMode Win2012R2 -InstallDns:$true -SafeModeAdministratorPassword $password -Force:$true"
promote_adds_command = "Install-ADDSDomainController -DomainName ${var.active_directory_domain} -InstallDns -Credential $credentials -SafeModeAdministratorPassword $password -Force:$true"
shutdown_command = "shutdown -r -t 10"
exit_code_hack = "exit 0"
powershell_command = "${local.import_command}; ${local.password_command}; ${local.install_ad_command}; ${local.configure_ad_command}; ${local.shutdown_command}; ${local.exit_code_hack}"
powershell_promote_command = "${local.password_command};${local.credentials_command}; ${local.install_ad_command}; ${local.promote_adds_command}; ${local.shutdown_command}; ${local.exit_code_hack}"
}
#creating a forest and promoting the Primary server as a DC
resource "azurerm_virtual_machine_extension" "create-active-directory-forest" {
name = "create-active-directory-forest"
virtual_machine_id = azurerm_windows_virtual_machine.virtual_machine[0].id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -Command \"${local.powershell_command}\""
}
SETTINGS
}
# Adding Secondary server to the Domain and promoting it as DC
resource "azurerm_virtual_machine_extension" "promote-to-domain-controller" {
name = "promote-to-domain-controller"
virtual_machine_id = azurerm_windows_virtual_machine.virtual_machine[1].id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -Command \"${local.powershell_promote_command}\""
}
SETTINGS
depends_on = [
azurerm_virtual_machine_extension.create-active-directory-forest
]
}
Note: Availability Set and Availability Zones cannot be configured together. It can be either or , If you want to use Zone
then Set
cannot be used. You can also refer this
Microsoft Community Blog
for more details.
Output:
For testing login to the secondary server using your domain admin username i.e. in my case [email protected]
and password.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |