Terraform Azure 在多个可用性集中创建虚拟机

Terraform Azure creating vm in multiple availability set

我正在尝试创建多个 Azure VM,但无法将 VM 分配给不同的 availability_set。请在下面查看我的代码:

模块“vm_dev”:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "2.82.0"
    }
  }
}
    
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg_dev" {
  name     = "MYORG_RG_DEV"
  location = var.location
}
  
resource "azurerm_network_interface" "node_master" {
  for_each = var.instances_master
    
  name                    = "${var.hostname_prefix}-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "${var.hostname_prefix}-${each.key}"
  
  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = var.subnet_id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}

resource "azurerm_linux_virtual_machine" "node_master" {
  for_each = var.instances_master

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  
  network_interface_ids = [azurerm_network_interface.node_master[each.key].id]

  os_disk {
    name                 = "${var.hostname_prefix}-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("id.pub")
  }

  disable_password_authentication = true
}

resource "azurerm_network_interface" "node_data" {
  for_each = var.instances_data

  name                    = "${var.hostname_prefix}-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "${var.hostname_prefix}-${each.key}"

  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = var.subnet_id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}

resource "azurerm_linux_virtual_machine" "node_data" {
  for_each = var.instances_data

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  
  network_interface_ids = [azurerm_network_interface.node_data[each.key].id]

  os_disk {
    name                 = "${var.hostname_prefix}-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("id.pub")
  }

  disable_password_authentication = true
}

vm.tf:

module "vm_dev" {
  source = "./vm_dev"

  vm_size           = "Standard_D4s_v3"
  hostname_prefix   = "myorg"
  group_name_prefix = var.group_prefix
  location          = var.location
  subnet_id         = local.subnet_id
  ssh_key           = local.ssh_public_key

  instances_master = {
    "aa-elastic-master-0" = { ip = "10.0.100.1" }
    "aa-elastic-master-1" = { ip = "10.0.100.2" }

    "xx-elastic-master-0" = { ip = "10.0.99.1" }
    "xx-elastic-master-1" = { ip = "10.0.99.2" }
  }

  instances_data = {
    "aa-elastic-data-0" = { ip = "10.0.100.3" }
    "aa-elastic-data-1" = { ip = "10.0.100.4" }
    "aa-elastic-data-2" = { ip = "10.0.100.5" }

    "xx-elastic-data-0" = { ip = "10.0.99.3" }
    "xx-elastic-data-1" = { ip = "10.0.99.4" }
    "xx-elastic-data-2" = { ip = "10.0.99.5" }

  }
}

这很好用,我可以创建 VM。到目前为止,每个 VM 都是在没有分配给 availability_set 的情况下创建的。我想指定每个 VM 属于哪个 availability_set,如下所示:

  instances_master = {
    "aa-elastic-master-0" = { ip = "10.0.100.1", as = "azurerm_availability_set.as_aamaster.id" }
    "aa-elastic-master-1" = { ip = "10.0.100.2", as = "azurerm_availability_set.as_aamaster.id" }

    "xx-elastic-master-0" = { ip = "10.0.99.1", as = "azurerm_availability_set.as_xxmaster.id" }
    "xx-elastic-master-1" = { ip = "10.0.99.2", as = "azurerm_availability_set.as_xxmaster.id" }
  }

  instances_data = {
    "aa-elastic-data-0" = { ip = "10.0.100.3", as = "azurerm_availability_set.as_aadata.id" }
    "aa-elastic-data-1" = { ip = "10.0.100.4", as = "azurerm_availability_set.as_aadata.id" }
    "aa-elastic-data-2" = { ip = "10.0.100.5", as = "azurerm_availability_set.as_aadata.id" }

    "xx-elastic-data-0" = { ip = "10.0.99.3", as = "azurerm_availability_set.as_xxdata.id" }
    "xx-elastic-data-1" = { ip = "10.0.99.4", as = "azurerm_availability_set.as_xxdata.id" }
    "xx-elastic-data-2" = { ip = "10.0.99.5", as = "azurerm_availability_set.as_xxdata.id" }

  }

在模块中添加以下代码:

resource "azurerm_availability_set" "as_aamaster" {
  name                = "${var.hostname_prefix}-as-aamaster"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}


resource "azurerm_linux_virtual_machine" "node_master" {
  for_each = var.instances_master

  name          = "${var.hostname_prefix}-${each.key}"
  computer_name = "${var.hostname_prefix}-${each.key}"
  size          = var.vm_size

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location

  availability_set_id   = each.value.as
  network_interface_ids = [azurerm_network_interface.node_master[each.key].id]
...

给我错误

Error: Cannot parse Azure ID: parse "azurerm_availability_set.as_aamaster.id": invalid URI for request

  on vm_dev/main.tf line 72, in resource "azurerm_linux_virtual_machine" "node_master":
  72:   availability_set_id   = each.value.as

如有任何建议,我们将不胜感激。

谢谢

我测试了你的代码,它失败了,错误如下:

所以,Ivan Ignatiev 建议您必须使用以下解决方案:

instances_master = {
    "aa-elastic-master-0" = { ip = "10.0.2.1", as = "${azurerm_availability_set.as_aamaster.id}" }
    "aa-elastic-master-1" = { ip = "10.0.2.2", as = "${azurerm_availability_set.as_aamaster.id}" }

    "xx-elastic-master-0" = { ip = "10.0.2.3", as = "${azurerm_availability_set.as_xxmaster.id}" }
    "xx-elastic-master-1" = { ip = "10.0.2.4", as = "${azurerm_availability_set.as_xxmaster.id}" }
  }

  instances_data = {
    "aa-elastic-data-0" = { ip = "10.0.2.5", as = "${azurerm_availability_set.as_aadata.id}" }
    "aa-elastic-data-1" = { ip = "10.0.2.6", as = "${azurerm_availability_set.as_aadata.id}" }
    "aa-elastic-data-2" = { ip = "10.0.2.7", as = "${azurerm_availability_set.as_aadata.id}" }

    "xx-elastic-data-0" = { ip = "10.0.2.8", as = "${azurerm_availability_set.as_xxdata.id}" }
    "xx-elastic-data-1" = { ip = "10.0.2.9", as = "${azurerm_availability_set.as_xxdata.id}" }
    "xx-elastic-data-2" = { ip = "10.0.2.10", as = "${azurerm_availability_set.as_xxdata.id}" }

  }

main.tf

resource "azurerm_network_interface" "node_master" {
  for_each = var.instances_master
    
  name                    = "ansuman-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "ansuman-${each.key}"
  
  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}
resource "azurerm_availability_set" "as_aamaster" {
  name                = "ansuman-as-aamaster"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}

resource "azurerm_availability_set" "as_xxmaster" {
  name                = "ansuman-as-xxmaster"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}


resource "azurerm_linux_virtual_machine" "node_master" {
  for_each = var.instances_master

  name          = "ansuman-${each.key}"
  computer_name = "ansuman-${each.key}"
  size          = "Standard_B1s"

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  availability_set_id   = each.value.as
  network_interface_ids = [azurerm_network_interface.node_master[each.key].id]

  os_disk {
    name                 = "ansuman-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  disable_password_authentication = true
}

resource "azurerm_network_interface" "node_data" {
  for_each = var.instances_data

  name                    = "ansuman-${each.key}-nic"
  resource_group_name     = azurerm_resource_group.rg_dev.name
  location                = azurerm_resource_group.rg_dev.location
  internal_dns_name_label = "ansuman-${each.key}"

  ip_configuration {
    name                          = "primary"
    primary                       = true
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address            = each.value.ip
    private_ip_address_allocation = "Static"
    private_ip_address_version    = "IPv4"
  }
}

resource "azurerm_availability_set" "as_aadata" {
  name                = "ansuman-as-aadata"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}
resource "azurerm_availability_set" "as_xxdata" {
  name                = "ansuman-as-xxdata"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  managed             = true
}

resource "azurerm_linux_virtual_machine" "node_data" {
  for_each = var.instances_data

  name          = "ansuman-${each.key}"
  computer_name = "ansuman-${each.key}"
  size          = "Standard_B1s"

  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = azurerm_resource_group.rg_dev.location
  availability_set_id   = each.value.as
  network_interface_ids = [azurerm_network_interface.node_data[each.key].id]

  os_disk {
    name                 = "ansuman-${each.key}-disk-os"
    storage_account_type = "StandardSSD_LRS"
    caching              = "ReadWrite"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  admin_username = "myuser"
  admin_ssh_key {
    username   = "myuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  disable_password_authentication = true
}

输出:

AnsumanBal-MT,这对我不起作用,我在上面添加了评论,但我能够通过以下方式解决这个问题:

"aa-elastic-master-0" = { ip = "10.0.2.1", as = "0" } 
"xx-elastic-master-0" = { ip = "10.0.2.3", as = "1" }

在模块中:

resource "azurerm_availability_set" "as_dev" {
  count               = 5
  name                = "${var.hostname_prefix}-dev-${element(var.availability_set_name, count.index)}-as"
  resource_group_name = azurerm_resource_group.rg_dev.name
  location            = var.location
}

为 azurerm_linux_virtual_machine 添加:

availability_set_id   = azurerm_availability_set.as_dev[each.value.as].id

变量:

variable "availability_set_name" {
  description = "Availability set name that the VMs will be created in"
  type        = list(any)
  default     = ["aamaster", "xxmaster", "aadata", ....]
}