hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.6k stars 4.65k forks source link

Cannot use UltraSSDEnabled VMs on DedicatedHostGroup #26555

Open randallt opened 4 months ago

randallt commented 4 months ago

Is there an existing issue for this?

Community Note

Terraform Version

1.6.6

AzureRM Provider Version

3.111.0

Affected Resource(s)/Data Source(s)

azurerm_dedicated_host_group

Terraform Configuration Files

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }

  subscription_id = "<sub_id>"
}

# Azure resource group to hold everything we're doing here
resource "azurerm_resource_group" "resource_group" {
  name     = "dedicated-host-group-RG"
  location = "eastus"
}

resource "azurerm_dedicated_host_group" "host_group" {
  name                        = "dedicated-host-group"
  resource_group_name         = azurerm_resource_group.resource_group.name
  location                    = azurerm_resource_group.resource_group.location
  zone                        = 1
  platform_fault_domain_count = 1
  automatic_placement_enabled = true
}

resource "azurerm_dedicated_host" "dedicated_host" {
  name                    = "dedicated-host"
  location                = azurerm_resource_group.resource_group.location
  dedicated_host_group_id = azurerm_dedicated_host_group.host_group.id
  sku_name                = "DDSv5-Type1"
  platform_fault_domain   = 0
  auto_replace_on_failure = false
}

# virtual network within the resource group
resource "azurerm_virtual_network" "vnet" {
  name                = "vnet"
  resource_group_name = azurerm_resource_group.resource_group.name
  location            = azurerm_resource_group.resource_group.location
  address_space       = ["10.13.0.0/16"]
}

# subnet within the virtual network
resource "azurerm_subnet" "subnet" {
  name                 = "subnet"
  resource_group_name  = azurerm_resource_group.resource_group.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes       = ["10.13.0.0/24"]
}

# network interface - sv
resource "azurerm_network_interface" "sv_nic" {
  name                = "sv-NIC"
  location            = azurerm_resource_group.resource_group.location
  resource_group_name = azurerm_resource_group.resource_group.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "Static"
    private_ip_address            = cidrhost("10.13.0.0/24", 101)
  }
}

resource "azurerm_windows_virtual_machine" "vm_sv" {
  name                    = "vm-sv"
  location                = azurerm_resource_group.resource_group.location
  zone                    = azurerm_dedicated_host_group.host_group.zone
  dedicated_host_group_id = azurerm_dedicated_host_group.host_group.id
  resource_group_name     = azurerm_resource_group.resource_group.name
  network_interface_ids   = [azurerm_network_interface.sv_nic.id]
  size                    = "Standard_D4ds_v5"
  admin_username          = "superuser"
  admin_password          = "<*superPassword342*>"

  os_disk {
    caching              = "ReadOnly"
    storage_account_type = "Standard_LRS"

    diff_disk_settings { # ephemeral OS disk
      option = "Local"
      placement = "ResourceDisk"
    }
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-datacenter-smalldisk-g2"
    version   = "17763.5696.240406"
  }

  additional_capabilities {
    ultra_ssd_enabled = "true"
  }
}

# managed ultra disk for work dir
resource "azurerm_managed_disk" "work_disk_sv" {
  name                 = "dedicated-host-sv-work-disk"
  location             = azurerm_resource_group.resource_group.location
  zone                 = azurerm_dedicated_host_group.host_group.zone
  resource_group_name  = azurerm_resource_group.resource_group.name
  storage_account_type = "UltraSSD_LRS"
  create_option        = "Empty"
  disk_size_gb         = "4"
  on_demand_bursting_enabled = "false"
}

# attach it to the VM
resource "azurerm_virtual_machine_data_disk_attachment" "disk_attachment_sv" {
  managed_disk_id    = azurerm_managed_disk.work_disk_sv.id
  virtual_machine_id = azurerm_windows_virtual_machine.vm_sv.id
  lun                = "10"
  caching            = "None"
}

Debug Output/Panic Output

Full debug output not needed. But this is the error message:

azurerm_windows_virtual_machine.vm_sv: Creating...
╷
│ Error: creating Windows Virtual Machine (Subscription: "946cdd29-da93-4471-b246-112bcebd0e6f"
│ Resource Group Name: "dedicated-host-group-RG"
│ Virtual Machine Name: "vm-sv"): performing CreateOrUpdate: unexpected status 409 (409 Conflict) with error: OperationNotAllowed: Resource 'vm-sv' cannot be placed on host group 'dedicated-host-group', since the host group does not support UltraSSD. If you would like to use UltraSSD VMs on Dedicated Host, please consider creating a new host group with UltraSSDEnabled capability.
│     Note that the value for UltraSSD capability is set to false by default if it is not specified, and it cannot be changed once the host group is created.
│
│   with azurerm_windows_virtual_machine.vm_sv,
│   on main.tf line 75, in resource "azurerm_windows_virtual_machine" "vm_sv":
│   75: resource "azurerm_windows_virtual_machine" "vm_sv" {

There appears to be no way to add the ultra SSD capability to the dedicated host group in terraform at this time.

Expected Behaviour

I should be able to add a block to the dedicated host group, like

  additional_capabilities {
    ultra_ssd_enabled = "true"
  }

Actual Behaviour

I'm not allowed to add the capability to the host group.

│ Error: Unsupported block type
│
│   on main.tf line 34, in resource "azurerm_dedicated_host_group" "host_group":
│   34:   additional_capabilities {
│
│ Blocks of type "additional_capabilities" are not expected here.

Steps to Reproduce

terraform apply

Important Factoids

No response

References

No response

randallt commented 4 months ago

I am able to use ARM Templates as a workaround, of course, but it was not fun since I'd never used them before. For reference:

templates/dedicated_host_group.json:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "resourceName": {
            "type": "string",
            "metadata": {
                "description": "The name of the Host group resource."
            }
        },
        "location": {
            "type": "string",
            "metadata": {
                "description": "The location of the Host group resource."
            }
        },
        "platformFaultDomainCount": {
            "type": "string",
            "metadata": {
                "description": "The platform fault domain count of the Host group resource."
            }
        },
        "zones": {
            "type": "array",
            "metadata": {
                "description": "The availability zone of the Host group resource"
            }
        },
        "ultraSSDEnabled": {
            "type": "string",
            "metadata": {
                "description": "Enable ultra SSD on hosts."
            }
        }
    },
    "resources": [
        {
            "type": "Microsoft.Compute/hostGroups",
            "name": "[parameters('resourceName')]",
            "apiVersion": "2021-11-01",
            "location": "[parameters('location')]",
            "properties": {
                "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]",
                "additionalCapabilities": {
                    "ultraSSDEnabled": "[parameters('ultraSSDEnabled')]"
                }
            },
            "tags": {},
            "zones": "[parameters('zones')]"
        }
    ],
    "outputs": {
        "hostGroupId": {
            "type": "string",
            "value": "[resourceId('Microsoft.Compute/hostGroups', parameters('resourceName'))]"
        }
    }
}

main.tf:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }

  subscription_id = "<sub_id>"
}

# Azure resource group to hold everything we're doing here
resource "azurerm_resource_group" "resource_group" {
  name     = "dedicated-host-group-RG"
  location = "eastus"
}

resource "azurerm_resource_group_template_deployment" "dedicated_host_group_arm" {
  name                = "dedicated-host-group"
  resource_group_name = azurerm_resource_group.resource_group.name
  deployment_mode     = "Incremental"
  template_content    = file("templates/dedicated_host_group.json",)
  parameters_content = jsonencode({
    "resourceName"              = { value = "dedicated-host-group" }
    "location"                  = { value = azurerm_resource_group.resource_group.location }
    "platformFaultDomainCount"  = { value = "1" }
    "zones"                     = { value = [ "1" ] }
    "ultraSSDEnabled"           = { value = "true" }
  })
}

resource "azurerm_dedicated_host" "dedicated_host" {
  name                    = "dedicated-host"
  location                = azurerm_resource_group.resource_group.location
  dedicated_host_group_id = jsondecode(azurerm_resource_group_template_deployment.dedicated_host_group_arm.output_content).hostGroupId.value
  sku_name                = "DDSv5-Type1"
  platform_fault_domain   = 0
  auto_replace_on_failure = false
}

# virtual network within the resource group
resource "azurerm_virtual_network" "vnet" {
  name                = "vnet"
  resource_group_name = azurerm_resource_group.resource_group.name
  location            = azurerm_resource_group.resource_group.location
  address_space       = ["10.13.0.0/16"]
}

# subnet within the virtual network
resource "azurerm_subnet" "subnet" {
  name                 = "subnet"
  resource_group_name  = azurerm_resource_group.resource_group.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes       = ["10.13.0.0/24"]
}

# network interface - sv
resource "azurerm_network_interface" "sv_nic" {
  name                = "sv-NIC"
  location            = azurerm_resource_group.resource_group.location
  resource_group_name = azurerm_resource_group.resource_group.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "Static"
    private_ip_address            = cidrhost("10.13.0.0/24", 101)
  }
}

resource "azurerm_windows_virtual_machine" "vm_sv" {
  name                    = "vm-sv"
  location                = azurerm_resource_group.resource_group.location
  zone                    = 1
  dedicated_host_id       = azurerm_dedicated_host.dedicated_host.id
  resource_group_name     = azurerm_resource_group.resource_group.name
  network_interface_ids   = [azurerm_network_interface.sv_nic.id]
  size                    = "Standard_D4ds_v5"
  admin_username          = "superuser"
  admin_password          = "<*superPassword342*>"

  os_disk {
    caching              = "ReadOnly"
    storage_account_type = "Standard_LRS"

    diff_disk_settings { # ephemeral OS disk
      option = "Local"
      placement = "ResourceDisk"
    }
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-datacenter-smalldisk-g2"
    version   = "17763.5696.240406"
  }

  additional_capabilities {
    ultra_ssd_enabled = "true"
  }
}

# managed ultra disk for work dir
resource "azurerm_managed_disk" "work_disk_sv" {
  name                 = "dedicated-host-sv-work-disk"
  location             = azurerm_resource_group.resource_group.location
  zone                 = 1
  resource_group_name  = azurerm_resource_group.resource_group.name
  storage_account_type = "UltraSSD_LRS"
  create_option        = "Empty"
  disk_size_gb         = "4"
  on_demand_bursting_enabled = "false"
}

# attach it to the VM
resource "azurerm_virtual_machine_data_disk_attachment" "disk_attachment_sv" {
  managed_disk_id    = azurerm_managed_disk.work_disk_sv.id
  virtual_machine_id = azurerm_windows_virtual_machine.vm_sv.id
  lun                = "10"
  caching            = "None"
}