azuresetvirtual-machineterraformavailability

Terraform - Azure - Create VM in availability set conditionally


Trying to create a VM in Terraform with and without an availability set. The idea is to use a template where if the availability set name is not provided, it defaults to empty, then the VM will not be added to the availability set. I did try using "count", as in 'count = var.avail_set != "" ? 1 : 0', but that did not work exactly as I wanted even though I had two sections that executed conditionally, I needed the name of the VM resource to be the same so I could add log analytics and backup later in the code. . Please see my code below:

    name = "${var.resource_group_name}"
}
data azurerm_subnet sndata02 {
    name = "${var.subnet_name}"
  resource_group_name = "${var.core_resource_group_name}"
  virtual_network_name = "${var.virtual_network_name}"
}
data azurerm_availability_set availsetdata02 {
  name = "${var.availability_set_name}"
  resource_group_name = "${var.resource_group_name}"
}
data azurerm_backup_policy_vm bkpoldata02 {
  name                = "${var.backup_policy_name}"
  recovery_vault_name = "${var.recovery_services_vault_name}"
  resource_group_name = "${var.core_resource_group_name}"
}
data azurerm_log_analytics_workspace law02 { 
  name                = "${var.log_analytics_workspace_name}"
  resource_group_name = "${var.core_resource_group_name}"
}
#===================================================================
# Create NIC
#===================================================================
resource "azurerm_network_interface" "vmnic02" {
  name                = "nic${var.virtual_machine_name}"
  location            = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name = "${var.resource_group_name}"

  ip_configuration {
    name                          = "ipcnfg${var.virtual_machine_name}"
    subnet_id                     = "${data.azurerm_subnet.sndata02.id}"
    private_ip_address_allocation = "Static"
    private_ip_address            = "${var.private_ip}"
  }
}
#===================================================================
# Create VM with Availability Set
#===================================================================
resource "azurerm_virtual_machine" "vm02" {
  count = var.avail_set != "" ? 1 : 0
  depends_on            = [azurerm_network_interface.vmnic02]
  name                  = "${var.virtual_machine_name}"
  location              = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name   = "${var.resource_group_name}"
  network_interface_ids = [azurerm_network_interface.vmnic02.id]
  vm_size               = "${var.virtual_machine_size}"
  availability_set_id   = "${data.azurerm_availability_set.availsetdata02.id}"
  tags                  = var.tags

  # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
  # NOTE: This may not be optimal in all cases.
  delete_os_disk_on_termination = true

  os_profile {
    computer_name  = "${var.virtual_machine_name}"
    admin_username = "__VMUSER__"
    admin_password = "__VMPWD__"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  storage_image_reference {
    id = "${var.image_id}"
  }

  storage_os_disk {
    name              = "${var.virtual_machine_name}osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Premium_LRS"
    os_type           = "Linux"     
  }

  boot_diagnostics {
    enabled = true
    storage_uri = "${var.boot_diagnostics_uri}"
  } 
}
#===================================================================
# Create VM without Availability Set
#===================================================================
resource "azurerm_virtual_machine" "vm03" {
  count = var.avail_set == "" ? 1 : 0
  depends_on            = [azurerm_network_interface.vmnic02]
  name                  = "${var.virtual_machine_name}"
  location              = "${data.azurerm_resource_group.rgdata02.location}"
  resource_group_name   = "${var.resource_group_name}"
  network_interface_ids = [azurerm_network_interface.vmnic02.id]
  vm_size               = "${var.virtual_machine_size}"
  # availability_set_id   = "${data.azurerm_availability_set.availsetdata02.id}"
  tags                  = var.tags

  # This means the OS Disk will be deleted when Terraform destroys the Virtual Machine
  # NOTE: This may not be optimal in all cases.
  delete_os_disk_on_termination = true

  os_profile {
    computer_name  = "${var.virtual_machine_name}"
    admin_username = "__VMUSER__"
    admin_password = "__VMPWD__"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  storage_image_reference {
    id = "${var.image_id}"
  }

  storage_os_disk {
    name              = "${var.virtual_machine_name}osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Premium_LRS"
    os_type           = "Linux"     
  }

  boot_diagnostics {
    enabled = true
    storage_uri = "${var.boot_diagnostics_uri}"
  } 
}
#===================================================================
# Set Monitoring and Log Analytics Workspace
#===================================================================
resource "azurerm_virtual_machine_extension" "oms_mma02" {
  count = var.bootstrap ? 1 : 0
  name                       = "${var.virtual_machine_name}-OMSExtension"
  virtual_machine_id         = "${azurerm_virtual_machine.vm02.id}"
  publisher                  = "Microsoft.EnterpriseCloud.Monitoring"
  type                       = "OmsAgentForLinux"
  type_handler_version       = "1.8"
  auto_upgrade_minor_version = true

  settings = <<SETTINGS
    {
      "workspaceId" : "${data.azurerm_log_analytics_workspace.law02.workspace_id}"
    }
  SETTINGS

  protected_settings = <<PROTECTED_SETTINGS
    {
      "workspaceKey" : "${data.azurerm_log_analytics_workspace.law02.primary_shared_key}"
    }
  PROTECTED_SETTINGS
}
#===================================================================
# Associate VM to Backup Policy
#===================================================================
resource "azurerm_backup_protected_vm" "vm02" {
  count = var.bootstrap ? 1 : 0
  resource_group_name = "${var.core_resource_group_name}"
  recovery_vault_name = "${var.recovery_services_vault_name}"
  source_vm_id        = "${azurerm_virtual_machine.vm02.id}"
  backup_policy_id    = "${data.azurerm_backup_policy_vm.bkpoldata02.id}"
}


Solution

  • The count property only controls the number of resources, for you, it means to create the VM or not, it won't change the configuration of the VM. It's not the right way for your situation.

    As I think, you can use the condition expression for the VM property availability_set_id like this:

    availability_set_id = var.avail_set != "" ? "${data.azurerm_availability_set.availsetdata02.id}" : ""