如何使用可用性集在两个不同的区域中配置 VM 并安装 Active Directory 域服务

How to configure the VMs in two different zones using Availability Sets and install the Active Directory Domain services

我正在尝试使用以下 terraform 代码在两个不同的区域中创建两个 windows 虚拟机:

## 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
  ]
}

我想使用可用性集在两个不同的区域中配置 VM,并使用 terraform 安装 Active Directory 域服务。

您可以使用类似下面的方法部署 2 个 VM 并在一个中创建一个新的活动目录林,而在另一个中您可以将其添加到域并将两者都提升为域控制器:

可用性集:

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 = "ansuman@contoso.local"
}

输出:


可用区:

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
]
}

注意:Availability Set and Availability Zones不能配置在一起。它可以是 或 ,如果你想使用 Zone 则不能使用 Set。你也可以参考这个 Microsoft Community Blog了解更多详情。

输出:

用于测试使用您的域管理员用户名登录到辅助服务器,即在我的情况下 ansuman@consto.local 和密码。