我有一个 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”(这只是此测试用例中创建的虚拟机的名称)。
我的做法完全错误吗?
使用 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
}
部署:
参考:
https://developer.hashicorp.com/terraform/language/functions/values
azurerm_virtual_machine_data_disk_attachment |资源 | Hashicorp/azurerm |地形 | Terraform 注册表