使用 for_each 创建不同数量的具有唯一 NIC 的 VM

Posted

技术标签:

【中文标题】使用 for_each 创建不同数量的具有唯一 NIC 的 VM【英文标题】:Creating varying number of VM's with unique NIC's using for_each 【发布时间】:2021-04-01 08:29:00 【问题描述】:

我正在尝试创建具有不同配置的不同数量的虚拟机。我在 azurerm_windows_virtual_machine 资源上设置 for_each 并循环遍历 tfvars 文件中设置的映射。该变量在模块中设置,但在 tfvars 文件中定义。

我希望能够创建 x 个虚拟机,每个虚拟机都连接一个唯一的 NIC。我能够创建虚拟机,但配置失败,因为 NIC 不是唯一的。我尝试使用相同的变量添加 for_each,但出现以下错误:

Error: Incorrect attribute value type

  on ../modules/compute/windows_vm/windows_vm.tf line 96, in resource "azurerm_network_interface_application_security_group_association" "application_security_group_association":
  96:   network_interface_id          = [azurerm_network_interface.network_interface[each.key].id]

Inappropriate value for attribute "network_interface_id": string required.


Error: Incorrect attribute value type

  on ../modules/compute/windows_vm/windows_vm.tf line 96, in resource "azurerm_network_interface_application_security_group_association" "application_security_group_association":
  96:   network_interface_id          = [azurerm_network_interface.network_interface[each.key].id]

Inappropriate value for attribute "network_interface_id": string required.

这是我的代码:

# VM Network Interface
resource "azurerm_network_interface" "network_interface" 
  for_each                      = var.servers
  name                          = "nic-$var.environment-$var.directorate-$var.business_unit-$var.vm_identifier$each.value.name"
  resource_group_name           = var.resource_group
  location                      = var.location
  enable_ip_forwarding          = "false"
  enable_accelerated_networking = "false"

  ip_configuration 
    name                          = "ipconfig1"
    subnet_id                     = data.azurerm_subnet.subnet.id
    private_ip_address_allocation = "Dynamic"
    primary                       = "true"
  
  


# Application Security Group
resource "azurerm_application_security_group" "application_security_group" 
  name                = "asg-$var.environment-$var.directorate-$var.business_unit-$var.vm_identifier"
  resource_group_name = var.resource_group
  location            = var.location


resource "azurerm_network_interface_application_security_group_association" "application_security_group_association" 
  for_each                      = var.servers
  network_interface_id          = [azurerm_network_interface.network_interface[each.key].id]
  application_security_group_id = azurerm_application_security_group.application_security_group.id
  


resource "azurerm_network_interface_security_group_association" "network_security_group_association" 
  for_each                  = var.servers
  network_interface_id      = [azurerm_network_interface.network_interface[each.key].id]
  network_security_group_id = azurerm_network_security_group.network_security_group.id


# Azure Virtual Machine
resource "azurerm_windows_virtual_machine" "virtual_machine" 
  for_each                         = var.servers
  name                             = "vm-$var.environment-$var.vm_identifier$each.value.name"
  location                         = var.location
  resource_group_name              = var.resource_group
  zone                             = each.value.zone
  size                             = var.vm_size
  network_interface_ids            = [azurerm_network_interface.network_interface[each.key].id]
  computer_name                    = "$var.vm_identifier$each.value.name"
  admin_username                   = xxxx
  admin_password                   = xxxx
  provision_vm_agent               = "true"
  source_image_id                  = data.azurerm_shared_image.shared_image.id


  boot_diagnostics 
    storage_account_uri = data.azurerm_storage_account.diag_storage_account.primary_blob_endpoint
  

  os_disk 
    name                      = "vm-$var.environment-$var.directorate-$var.business_unit-$var.vm_identifier-os$each.value.name"
    caching                   = "ReadWrite"
    storage_account_type      = "Premium_LRS"
  

  depends_on = [azurerm_network_interface.network_interface]

for_each 中使用并在模块 variables.tf 中设置的根模块内的变量:

variable "servers" 
  description = "Variable for defining each instance"

模块中映射到每个环境的每个 tfvar 的变量:

variable "desktop_servers" 
  description = "Variable for defining each instance"


variable "db_servers" 
  description = "Variable for defining each instance"

然后在 tfvars 中定义如下:

desktop_servers = 
  "Server_1" = 
    name = 1,
    zone = 1
  
  "Server_2" = 
    name = 2,
    zone = 2
  
  "Server_3" = 
    name = 3,
    zone = 3
  


db_servers = 
  "Server_1" = 
    name = 1,
    zone = 1
  

【问题讨论】:

【参考方案1】:

您正在将一个列表分配给network_interface_id,但它应该只是一个字符串。

因此,而不是:

network_interface_id          = [azurerm_network_interface.network_interface[each.key].id]

应该是

network_interface_id          = azurerm_network_interface.network_interface[each.key].id

【讨论】:

以上是关于使用 for_each 创建不同数量的具有唯一 NIC 的 VM的主要内容,如果未能解决你的问题,请参考以下文章

使用具有 for_each 集的模块的输出值

具有下游依赖项的 Terraform 条件“for_each”

将 aws 资源导入具有 for_each 的 terraform 模块

Caffe:具有不同数量标签的多标签图像

仅选择最多具有 N 个唯一值的列

工厂创建具有不同数量关系的多个模型