Azure Terraform 使用托管磁盘部署 Linux VM

问题描述 投票:0回答:1

我有一个 Terraform 模块来创建 Linux VM,当我只需要它拥有主操作系统磁盘时,它工作得很好。

但我现在需要能够使用额外的托管磁盘数据磁盘来部署 Linux VM,但我不知道如何循环附加所创建的磁盘。

我的模块代码如下所示:

# VM depends on NIC
# Create network interface first
resource "azurerm_network_interface" "nic" {
  for_each = var.virtual_machines

  name                = each.value.nic_name
  location            = var.location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = each.value.ip_configuration.name
    subnet_id                     = each.value.ip_configuration.subnet_id
    private_ip_address_allocation = each.value.ip_configuration.private_ip_address_allocation
    private_ip_address            = each.value.ip_configuration.private_ip_address
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  for_each = var.virtual_machines

  name                  = each.value.name
  computer_name         = each.value.computer_name
  location              = var.location
  resource_group_name   = var.resource_group_name
  size                  = var.vm_size
  network_interface_ids = [azurerm_network_interface.nic[each.key].id]
  availability_set_id   = var.availability_set_name != "" ? azurerm_availability_set.avset[0].id : null
  admin_username        = var.admin_username
  admin_ssh_key {
    username   = var.admin_username
    public_key = file("~/.ssh/id_rsa.pub")
  }

  dynamic "os_disk" {
    for_each = {
      for index, os_disk in each.value.os_disk : os_disk.name => os_disk
    }
    content {
      name                 = os_disk.value.name
      caching              = os_disk.value.caching
      storage_account_type = os_disk.value.storage_account_type
      disk_size_gb         = os_disk.value.disk_size_gb
    }
  }

  dynamic "source_image_reference" {
    for_each = {
      for index, source_image_reference in each.value.source_image_reference : source_image_reference.publisher => source_image_reference
    }
    content {
      publisher = source_image_reference.value.publisher
      offer     = source_image_reference.value.offer
      sku       = source_image_reference.value.sku
      version   = source_image_reference.value.version
    }
  }
}

# Optional availability set
resource "azurerm_availability_set" "avset" {
  count                       = var.availability_set_name != "" ? 1 : 0
  name                        = var.availability_set_name
  location                    = var.location
  resource_group_name         = var.resource_group_name
  managed                     = true
  platform_fault_domain_count = 2 # For managed disks this can only be in the range of 1-2
}

# Optional data disk(s)
resource "azurerm_managed_disk" "disk" {
  for_each = {
    for index, data_disk in var.data_disks : data_disk.name => data_disk
  }

  name                 = each.value.name
  location             = var.location
  resource_group_name  = var.resource_group_name
  create_option        = "Empty"
  storage_account_type = each.value.storage_account_type
  disk_size_gb         = each.value.disk_size_gb
}

# Optional data disk attachment to VM
resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach" {
  for_each = {
    for index, data_disk in var.data_disks : data_disk.name => data_disk
  }

  managed_disk_id    = azurerm_managed_disk.disk[each.key].id
  virtual_machine_id = azurerm_linux_virtual_machine.vm[each.key].id
  lun                = each.value.lun
  caching            = each.value.caching
}

我尝试基于逻辑进行创建:“如果提供了任何数据磁盘,则创建它们并将它们附加到您正在创建的虚拟机”。

data_disk 作为对象列表提供:

variable "data_disks" {
  type = list(object({
    name                 = string
    caching              = string
    storage_account_type = string
    disk_size_gb         = number
    lun                  = number
  }))
  description = "(Optional) Values for any additional data disks"
}

我正在使用这个测试:

locals {
  primary_location = "UK South"
  environment = "dev"
  rg_name = "rg-temp"
}

module "linux_vm" {
  source = "../"

  location              = local.primary_location
  resource_group_name   = local.rg_name
  vm_size               = "Standard_B2ms"
  admin_username        = "admin " # Default user to create?
  admin_password        = "RandomPassword000."
  availability_set_name = ""
  tags                  = {}

  virtual_machines = {
    "linux-001" = {
      name          = "linux-001"
      computer_name = "linux-001"
      os_disk = [
        {
          name                 = "disk-001"
          caching              = "ReadWrite"
          storage_account_type = "StandardSSD_LRS"
          disk_size_gb         = 128
        }
      ]

      source_image_reference = [
        {
          publisher = "Canonical"
          offer     = "UbuntuServer"
          sku       = "20.04-LTS"
          version   = "latest"
        }
      ]

      nic_name = "nic-dev-linux-001"
      ip_configuration = {
        name                          = "linux-001"
        subnet_id                     = "/subscriptions/e286703f-8ba4-4a0d-xxxx-xxxxxxxxxxxx/resourceGroups/shared-networks/providers/Microsoft.Network/virtualNetworks/shared-vnet-10/subnets/1-24"
        private_ip_address_allocation = "Static"
        private_ip_address            = "10.10.10.20"
      }
    }
  }

  data_disks = [
      {
        name                 = "data-disk-001"
        caching              = "ReadWrite"
        storage_account_type = "StandardSSD_LRS"
        disk_size_gb         = 128
        lun                  = 5
      }
    ]
}

但是无论我如何尝试获取它创建的 linux 虚拟机的 id 以与磁盘附加块一起使用,我都会收到错误。

尝试[每个键]

virtual_machine_id = azurerm_linux_virtual_machine.vm[each.key].id

获取:

│ Error: Invalid index
│
│   on ../main.tf line 90, in resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach":
│   90:   virtual_machine_id = azurerm_linux_virtual_machine.vm[each.key].id
│     ├────────────────
│     │ azurerm_linux_virtual_machine.vm is object with 1 attribute "linux-001"
│     │ each.key is "data-disk-001"
│
│ The given key does not identify an element in this collection value.

尝试[0]

 virtual_machine_id = azurerm_linux_virtual_machine.vm[*].id

获取:

│ Error: Invalid index
│
│   on ../main.tf line 90, in resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach":
│   90:   virtual_machine_id = azurerm_linux_virtual_machine.vm[0].id
│     ├────────────────
│     │ azurerm_linux_virtual_machine.vm is object with 1 attribute "linux-001"
│
│ The given key does not identify an element in this collection value. An object only supports looking up attributes by name, not by numeric index.
╵

并尝试[*]

virtual_machine_id = azurerm_linux_virtual_machine.vm[*].id

获取:

│ Error: Incorrect attribute value type
│
│   on ../main.tf line 90, in resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach":
│   90:   virtual_machine_id = azurerm_linux_virtual_machine.vm[*].id
│     ├────────────────
│     │ azurerm_linux_virtual_machine.vm is object with 1 attribute "linux-001"
│
│ Inappropriate value for attribute "virtual_machine_id": string required.
╵
╷
│ Error: Unsupported attribute
│
│   on ../main.tf line 90, in resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach":
│   90:   virtual_machine_id = azurerm_linux_virtual_machine.vm[*].id
│
│ This object does not have an attribute named "id".
╵

这些都没有找到正在创建的 Linux 虚拟机的“id”属性,有些建议该对象只有一个属性“linux-001”(这只是此测试用例中创建的虚拟机的名称)。

我的做法完全错误吗?

azure list for-loop terraform
1个回答
0
投票

使用 terraform 部署带有托管磁盘的 Linux VM

问题似乎在于您尝试在此处获取虚拟机 ID 的方式,您试图将磁盘附加到错误的虚拟机,因为您错误地引用了磁盘名称而不是虚拟机名称。

我尝试使用

value
函数更改引用来更新配置。

  virtual_machine_id = values(azurerm_linux_virtual_machine.vm)[0].id

通过引用数据磁盘附件的正确虚拟机来按照要求工作。

配置:

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = [var.address_space]
}


resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = [var.subnet_address_prefix]
}


resource "azurerm_availability_set" "avset" {
  count                       = var.availability_set_name != "" ? 1 : 0
  name                        = var.availability_set_name
  location                    = var.location
  resource_group_name         = var.resource_group_name
  managed                     = true
  platform_fault_domain_count = 2 
}


resource "azurerm_network_interface" "nic" {
  for_each = var.virtual_machines

  name                = each.value.nic_name
  location            = var.location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = each.value.ip_configuration.name
    subnet_id                     = azurerm_subnet.subnet.id 
    private_ip_address_allocation = each.value.ip_configuration.private_ip_address_allocation
    private_ip_address            = each.value.ip_configuration.private_ip_address
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  for_each = var.virtual_machines

  name                  = each.value.name
  computer_name         = each.value.computer_name
  location              = var.location
  resource_group_name   = var.resource_group_name
  size                  = var.vm_size
  network_interface_ids = [azurerm_network_interface.nic[each.key].id]
  availability_set_id   = var.availability_set_name != "" ? azurerm_availability_set.avset[0].id : null
  admin_username        = var.admin_username
 admin_password       = var.admin_password
  disable_password_authentication = false

  dynamic "os_disk" {
    for_each = {
      for index, os_disk in each.value.os_disk : os_disk.name => os_disk
    }
    content {
      name                 = os_disk.value.name
      caching              = os_disk.value.caching
      storage_account_type = os_disk.value.storage_account_type
      disk_size_gb         = os_disk.value.disk_size_gb
    }
  }

  dynamic "source_image_reference" {
    for_each = {
      for index, source_image_reference in each.value.source_image_reference : source_image_reference.publisher => source_image_reference
    }
    content {
      publisher = source_image_reference.value.publisher
      offer     = source_image_reference.value.offer
      sku       = source_image_reference.value.sku
      version   = source_image_reference.value.version
    }
  }
}


resource "azurerm_managed_disk" "disk" {
  for_each = {
    for index, data_disk in var.data_disks : data_disk.name => data_disk
  }

  name                 = each.value.name
  location             = var.location
  resource_group_name  = var.resource_group_name
  create_option        = "Empty"
  storage_account_type = each.value.storage_account_type
  disk_size_gb         = each.value.disk_size_gb
}


resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_attach" {
  for_each = {
    for index, data_disk in var.data_disks : data_disk.name => data_disk
  }

  managed_disk_id    = azurerm_managed_disk.disk[each.key].id
  virtual_machine_id = values(azurerm_linux_virtual_machine.vm)[0].id
  lun                = each.value.lun
  caching            = each.value.caching
}

部署:

enter image description here

enter image description here

参考:

https://developer.hashicorp.com/terraform/language/functions/values

azurerm_virtual_machine_data_disk_attachment |资源 | Hashicorp/azurerm |地形 | Terraform 注册表

© www.soinside.com 2019 - 2024. All rights reserved.