I seem to be having trouble creating a module for VMs that leverage availability zones. It appears in terraform the zones attribute supports only one item per VM, so iteration for the VM is needed for each availability zone, i.e 1,2, or 3.
This works fine when it is just a VM and no data disks needing attached, however, we have some VMs that require multiple data disks, sometimes 1, 2, or more. The data disk creation has a count on the number of disks supplied in the data disk variable. This causes problems as you cannot have a count and a for_each loop in conjunction with each other in the same resource block when you go to associate the disks to azure VM. Need help is attempting to resolve that, i’ve tried removing the for_each, adding a dynamic block for the azure_virtual_machine_id but it did not like that. Not sure what else it could be.
Terraform Code
resource "azurerm_virtual_machine" "vm" {
for_each = toset(var.availability_zone)
name = var.vm_name
location = var.location
resource_group_name = var.resource_group_name
network_interface_ids = [azurerm_network_interface.nic.id]
vm_size = var.size
availability_set_id = azurerm_availability_set.av_set.id
tags = var.tags
zones = each.value
identity {
type = "SystemAssigned"
}
boot_diagnostics {
enabled = true
storage_uri = ""
}
storage_os_disk {
name = "${var.vm_name}-osDisk"
caching = var.os_disk_caching
create_option = "FromImage"
managed_disk_type = var.os_managed_disk_type
disk_size_gb = var.os_disk_size_gb
}
os_profile {
computer_name = var.vm_name
admin_username = var.admin_username
admin_password = var.admin_password
}
storage_image_reference {
publisher = var.image_publisher
offer = var.image_offer
sku = var.image_sku
version = var.image_version
}
os_profile_windows_config {
provision_vm_agent = true
enable_automatic_upgrades = true
}
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
}
resource "azurerm_managed_disk" "data" {
count = var.data_disk_count
name = "${var.vm_name}-DataDisk-${count.index + 1}"
location = var.location
resource_group_name = var.resource_group_name
storage_account_type = var.data_disk_storage_account_type
create_option = "Empty"
disk_size_gb = var.data_disk_size_gb
tags = var.tags
}
resource "azurerm_virtual_machine_data_disk_attachment" "data" {
for_each = azurerm_virtual_machine.vm
count = var.data_disk_count
managed_disk_id = azurerm_managed_disk.data[count.index].id
for_each = azurerm_virtual_machine.vm
virtual_machine_id = azurerm_virtual_machine.vm[each.key].id
lun = count.index + 5
caching = var.data_disk_caching
}
Error
Error: Invalid combination of "count" and "for_each"
│
│ on modulesvirtual_machinemain.tf line 92, in resource "azurerm_virtual_machine_data_disk_attachment" "data":
│ 92: for_each = azurerm_virtual_machine.vm
│
│ The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.
Then if you omit the for_each loop in the azurerm_virtual_machine_data_disk_attachment resource block the error becomes:
Error: Missing resource instance key
│
│ on modulesvirtual_machinemain.tf line 92, in resource "azurerm_virtual_machine_data_disk_attachment" "data":
│ 92: virtual_machine_id = azurerm_virtual_machine.vm.id
│
│ Because azurerm_virtual_machine.vm has "for_each" set, its attributes must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ azurerm_virtual_machine.vm[each.key]