I want to deploy a bunch of resources only by calling one self written module:
module "transit-gateway-sea" {
source = "./modules/transit-gateway"
location = "southeastasia"
vnet_address_space = [local.sea_vnet_address_space]
subnet_address_spaces = {
mgmt0 = [cidrsubnets(local.sea_vnet_address_space, 2, 2, 2, 2, )[0]]
wan0 = [cidrsubnets(local.sea_vnet_address_space, 2, 2, 2, 2, )[1]]
lan0 = [cidrsubnets(local.sea_vnet_address_space, 2, 2, 2, 2, )[2]]
}
bastion_subnet = [cidrsubnets(local.sea_vnet_address_space, 2, 2, 2, 2, )[3]]
ha_enabled = true
}
Inside of this module a few things happen but the import thing to know is, that based on the region I assign a value to a local, like this:
locals {
country_code = (var.location == "southeastasia" ? "-sea" :
var.location == "westeurope" ? "-weu" :
var.location == "northcentralus" ? "-ncus" :
var.location == "brazilsouth" ? "-bs" :
var.location == "northeurope" ? "-neu" :
""
)
primary_zone = (var.location == "southeastasia" ? "1" :
var.location == "westeurope" ? "1" :
var.location == "brazilsouth" ? "1" :
var.location == "northeurope" ? "1" :
null
)
secondary_zone = (var.location == "southeastasia" ? "2" :
var.location == "westeurope" ? "2" :
var.location == "brazilsouth" ? "2" :
var.location == "northeurope" ? "2" :
null
)
}
Please find the code for the VMs and the availability sets and zones below. The secondary vm is only deployed if ha_enabled variable is to true during the module call. Same logic applies somehow to the availability set, but it depends on the region whether Avail Zones are supported in that region or not. If not the Avail Set should be deployed and both VMs should be assigned to this Avail Set.
resource "azurerm_availability_set" "aset" {
count = local.primary_zone != "1" ? 0 : 1
name = "silverpeak-sdwan${local.country_code}-aset"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
lifecycle {
ignore_changes = [
tags
]
}
}
resource "azurerm_linux_virtual_machine" "primary-vm" {
count = 1
name = "silverpeak-sdwan${local.country_code}-primary-vm"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = var.vm_size
admin_username = "adminuser"
admin_password = random_password.admin-password-primary.result
disable_password_authentication = false
zone = local.primary_zone
encryption_at_host_enabled = true
allow_extension_operations = false
availability_set_id = local.primary_zone != "1" ? azurerm_availability_set.aset[count.index].id : null
network_interface_ids = [
for nics in azurerm_network_interface.primary-nics : nics.id
]
os_disk {
name = "silverpeak-sdwan${local.country_code}-primary-vm-osdisk"
caching = "ReadWrite"
storage_account_type = var.storage_account_type
}
source_image_reference {
publisher = "silver-peak-systems"
offer = "silver_peak_edgeconnect_vwan"
sku = "silver_peak_edgeconnect_vwan_8_3_0_14"
version = "8.3.0"
}
plan {
name = "silver_peak_edgeconnect_vwan_8_3_0_14"
publisher = "silver-peak-systems"
product = "silver_peak_edgeconnect_vwan"
}
lifecycle {
ignore_changes = [
tags
]
}
}
resource "azurerm_linux_virtual_machine" "secondary-vm" {
count = var.ha_enabled ? 1 : 0
name = "silverpeak-sdwan${local.country_code}-secondary-vm"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = var.vm_size
admin_username = "adminuser"
admin_password = random_password.admin-password-secondary.result
disable_password_authentication = false
zone = local.secondary_zone
encryption_at_host_enabled = true
allow_extension_operations = false
availability_set_id = local.secondary_zone != "2" ? azurerm_availability_set.aset[count.index].id : null
network_interface_ids = [
for nics in azurerm_network_interface.secondary-nics : nics.id
]
os_disk {
name = "silverpeak-sdwan${local.country_code}-secondary-vm-osdisk"
caching = "ReadWrite"
storage_account_type = var.storage_account_type
}
source_image_reference {
publisher = "silver-peak-systems"
offer = "silver_peak_edgeconnect_vwan"
sku = "silver_peak_edgeconnect_vwan_8_3_0_14"
version = "8.3.0"
}
plan {
name = "silver_peak_edgeconnect_vwan_8_3_0_14"
publisher = "silver-peak-systems"
product = "silver_peak_edgeconnect_vwan"
}
lifecycle {
ignore_changes = [
tags
]
}
}
so based on the location I deploy an availability set or availibility zones. From my point of view this makes absolutely sense but I get I error message which I do not understand. I hope some of you guys can help me.
It looks like somehow azurerm_availability_set.aset
is empty, but it shouldn't based on the condition in the count parameter. I hope some of you guys can help me.
│ Error: Invalid index
│
│ on modules/transit-gateway/vm.tf line 51, in resource "azurerm_linux_virtual_machine" "primary-vm":
│ 51: availability_set_id = local.primary_zone != "1" ? azurerm_availability_set.aset[count.index].id : null
│ ├────────────────
│ │ azurerm_availability_set.aset is empty tuple
│ │ count.index is 0
│
│ The given key does not identify an element in this collection value: the
│ collection has no elements.
╵
╷
│ Error: Invalid index
│
│ on modules/transit-gateway/vm.tf line 97, in resource "azurerm_linux_virtual_machine" "secondary-vm":
│ 97: availability_set_id = local.secondary_zone != "2" ? azurerm_availability_set.aset[count.index].id : null
│ ├────────────────
│ │ azurerm_availability_set.aset is empty tuple
│ │ count.index is 0
│
│ The given key does not identify an element in this collection value: the
│ collection has no elements.
╵
##[error]Error: Terraform Plan failed with exit code: 1
CodePudding user response:
I found out what was wrong with the code. So everyone else who is doing similar things with other or same resources double check your condition and double check the logic of your code.
for the availability set resource I did this:
count = local.primary_zone != "1" ? 0 : 1
but I should have done this:
count = local.primary_zone == "1" ? 0 : 1
and now it works! Now an availability set is created and VMs added automatically when availability zones are not available in a certain region.