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

azurerm_windows_virtual_machine fails to create when referencing a "specialised" shared gallery image. #7772

Open woter1832 opened 4 years ago

woter1832 commented 4 years ago

Community Note

Terraform (and AzureRM Provider) Version

Terraform v0.12.28
+ provider.azuread v0.10.0
+ provider.azurerm v2.18.0

Affected Resource(s)

Terraform Configuration Files

resource "azurerm_windows_virtual_machine" "pool" {
  for_each = {
    for key, i in local.vm_config :
    key => i
  }

  name                  = each.value.vm_name
  resource_group_name   = var.resource_group_name
  location              = var.location
  size                  = each.value.vm_size
  admin_username        = each.value.admin_username
  admin_password        = each.value.admin_password
  network_interface_ids = each.value.network_interface_ids
  license_type          = each.value.license_type
  timezone              = each.value.timezone

  source_image_id       = each.value.source_image_id
 #redacted source_image_id value: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Compute/galleries/myGallary/images/windows_server_2019/versions/0.0.1

  tags                  = merge(var.tags, { purpose = each.value.purpose }, { node = each.value.node_key + 1 })

  os_disk {
    caching              = each.value.os_disk_caching
    storage_account_type = each.value.os_disk_storage_account_type
  }

  # source_image_reference {
  #   publisher = "MicrosoftWindowsServer"
  #   offer     = "WindowsServer"
  #   sku       = "2019-Datacenter"
  #   version   = "latest"
  # }

Debug Output

Panic Output

Expected Behavior

Deploy two Windows VMs from "Shared Gallery Image"

Actual Behavior

A spurious error that does not relate to the issue.

module.compute_region_0.module.windows_virtual_machine.azurerm_windows_virtual_machine.pool["1"]: Creating...
Error: creating Windows Virtual Machine "vm1" (Resource Group "rgvmimagedemo"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="Parameter 'osProfile' is not allowed." Target="osProfile"

  on ..\azurerm_windows_virtual_machine\main.tf line 82, in resource "azurerm_windows_virtual_machine" "pool":
  82: resource "azurerm_windows_virtual_machine" "pool" {

Repeats for VM2. (Line 82 is the begining of the resource: resource "azurerm_windows_virtual_mahine" "pool" {)

If this isn't a bug, please consider updating the document that would resolve my mistake. Perhaps an example of using source_image_id.

Steps to Reproduce

  1. terraform apply

Important Factoids

This may be related to #5998 although the error is different.

Plan succeeds.

I did a test by creating the old os_profile{} block, adding admin_username and admin_password which made the plan fail.

If this is the same regression as mentioned in #5998, can you check azurerm_linux_virtual_machine too, please?

If I comment out source_image_id and use source_image_reference instead, apply works and the VMs deploy.

T. I. A.

References

There is an unanswered related question on your discuss site: https://discuss.hashicorp.com/t/unable-to-create-azure-windows-vm/6672

woter1832 commented 4 years ago

The documentation is not clear on exactly what value source_image_id takes, however, I have tried it pointing to the image rather than the version too, with the same error:

I also note resource explorer does not show any galleries resources.

source_image_id value: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Compute/galleries/myGallary/images/windows_server_2019
woter1832 commented 4 years ago

To try and rule out any stupidity on my part, I've used the DATA source: azurerm_shared_image_version and consumed the id attribute reference. Same result.

woter1832 commented 4 years ago

At the behest of Terraform support, I created a cut-down version of the code which still gave the same error.

# #############################################
# VARIABLES
# #############################################

variable "client_secret" {
    type = string
}

# #############################################
# PROVIDERS
# #############################################

provider "azurerm" {
    subscription_id = "00000000-0000-0000-0000-000000000000"
    tenant_id       = "00000000-0000-0000-0000-000000000000"
    client_id       = "00000000-0000-0000-0000-000000000000"
    client_secret   = var.client_secret
    version         = "2.18.0"
    features {}
}

# #############################################
# VERSION AND REMOTE STATE
# #############################################

terraform {
    required_version = ">=0.12"
}

resource "azurerm_windows_virtual_machine" "test" {
    name                  = "myVm01"
    resource_group_name   = "rgvmimagedemo"
    location              = "westeurope"
    size                  = "Standard_B1s"
    admin_username        = "LocalAdmin"
    admin_password        = "Pa$$w0rd!2345"
    network_interface_ids = ["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Network/networkInterfaces/nic1"]
    license_type          = "Windows_Server"
    timezone              = "GMT Standard Time"

    #source_image_id       = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Compute/galleries/myGallery01/images/windows_server_2019/versions/0.0.2"
    #source_image_id       = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Compute/galleries/myGallery01/images/windows_server_2019"
    #source_image_id       = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rgvmimagedemo/providers/Microsoft.Compute/galleries/myGallery01/images/windows_server_2019_capture/versions/0.0.3"
    source_image_id        = ""
    tags                  = {purpose = "Test OS Images gallery deployment"}

    os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
    }

    boot_diagnostics {
        storage_account_uri = "https://someSA.blob.core.windows.net"
    }
}

After rereading some of the MS docs, osimage seems to relate to Generalised vs. Specialised VMs. I was trying to deploy a Specialised image, however, after creating a Generalised image my VMs deployed. Specialised VMs cause this error, so it looks like Specialised VMs aren't supported or there's a bug - they work in PowerShell.

I am rather confused about the different methods to create images. On one hand, there is the "Managed Image", created by sysprep'ing (Generalise) + OOBE, created by clicking Capture in the VM blade, whilst on the other hand, there is a newer method which should work directly from a VM without having to convert it to an image (as described here). Using this method, to get the VM into a Generalised state, I had to run sysprep on the VM (shutdown) and then deallocate it before setting the VM to Generalised, by using this API call. I was then able to create the "Shared Gallery Image" and version using the PowerShell (in Microsoft's tutorial) setting -OSType Generalize This allowed my Terraform code to work. I should add that I could create a Specialised image straight from an existing VM without having to run sysprep and then deploy it using PowerShell.

Please could someone from Hashicorp / MS confirm if my findings are accurate, in that Specialised VM's are not supported/do not work?

If the latter, is this something that can be fixed and if not, can we have a note added to the documentation, please?

I'll leave this open to allow Hashicorp to respond, but essentially, I seem to have resolved the issue.

ArcturusZhang commented 4 years ago

Hi @woter1832 thanks for this issue!

Despite that now azurerm provider supports creating specialized image, it does not support provision VMs or VMSSes by using the specialized images. It is implementing in PR #7524 but it is currently blocked by some inconsistency in the compute API of azure. Please stay tuned.

Thanks!

satyakrish commented 3 years ago

(upvoted this) Any updates on this issue, we have a scenario where the application requires specific user groups to be present and so we would like to use specialized images . But facing the same issues as explained in this issue while trying to create a vm using specialized image. Support for this feature would really help us.

TheBlackMini commented 3 years ago

I'm also stuck with this issue but for azurerm_linux_virtual_machine instead.

SylvainMartel commented 3 years ago

Same problem here. Do I understand that terraform is unable to deploy "specialized" image at all?

dkarlovi commented 3 years ago

@kinwolfqc it appears so, I have exactly the same issue with the latest Azure provider. There doesn't seem to be a solution at this moment other than creating a generalized version of the image.

dkarlovi commented 3 years ago

I can confirm that using a generalized image with source_image_id works. The only thing is, creating generalized images is IMO a PITA if you don't need them. :|

burnedikt commented 3 years ago

I managed to create a (Windows) VM based on a specialised image (version) from a shared image gallery with terraform by relying on the (deprecated) azurerm_virtual_machine resource instead of azurerm_windows_virtual_machine. I am aware that this is not a future-proof solution but it might help someone as a temporary workaround.

abdullah-lt commented 2 years ago

Is there any update on this? If not, can we update the document to reflect the same?

SteFletcher commented 2 years ago

I'm having the exact same issue with a linux vm + specialized image via the azurerm_linux_virtual_machine.

ChrisPetr0 commented 2 years ago

I'm having the exact same issue with a linux vm + specialized image via the azurerm_linux_virtual_machine.

I am having this same issue as well with Linux VM. Even though this was marked as off topic, wanted to add another data point. With the old resource of azurerm_virtual_machine, it does indeed work.

lingclound commented 2 years ago

this issue seems last more than 2 years, no final solution until now, is there any workaround , thanks in advance

ChrisPetr0 commented 2 years ago

this issue seems last more than 2 years, no final solution until now, is there any workaround , thanks in advance

My "workaround" was to generalize the image... Heh, that's all I got.

bn-jswick commented 1 year ago

Hi, Is there any news on this? I ran into this issue today while trying to create VMs using some internal custom images.

Terraform v1.3.8
on linux_amd64
+ provider registry.terraform.io/hashicorp/azuread v2.33.0
+ provider registry.terraform.io/hashicorp/azurerm v3.43.0
+ provider registry.terraform.io/hashicorp/random v3.4.3
swinster commented 1 year ago

I guess there are no updates.... It's been 3 years now :(

swinster commented 1 year ago

FWIW, I was able to get a specialised image working with the azurerm_virtual_machine resource type (as mentioned by both @burnedikt and @ChrisPetr0 above), but ONLY when using a base VM that used a "Standard" security type (as opposed to "Trusted Launch" security type, which is becoming the norm). I believe Gen 1 VMs always use Standard security, and Gen 2 VMs usually use Trusted Launch security by default (the Azure CLI will be updated in November).

To prove this out, it is possible to force deployment of a Windows 11 Gen 2 Standard Security VM as a base image using the Azure CLI on which we can customise and specialise, for example:

az group create --name myResourceGroup --location eastus
az vm create --resource-group myResourceGroup --name myVM --image "MicrosoftWindowsDesktop:windows-11:win11-22h2-pro:22621.2134.230801" --public-ip-sku Standard --admin-username testadmin --admin-password Password1234! --security-type Standard

Then, I modify and capture a specialised image in the Azure Compute Gallery. I can then use something like this Terraform to deploy a working VM from this specialised image:

resource "azurerm_virtual_machine" "windows" {
  name                        = "testingvm"
  resource_group_name         = "${data.azurerm_resource_group.main.name}"
  location                    = "${data.azurerm_resource_group.main.location}"

  vm_size                     = "Standard_B2s"
  network_interface_ids       = [azurerm_network_interface.winnic.id]

  storage_image_reference {
    id                        = "/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx/resourceGroups/myComputeGallery_RG/providers/Microsoft.Compute/galleries/myComputeGallery/images/Win11Gen2StandardSecuritySpecialised"
  }

  storage_os_disk {
    name                      = "${var.prefix}-osdisk"
    caching                   = "ReadWrite"
    create_option             = "FromImage"
    managed_disk_type         = "Standard_LRS"
  }
}

If we do the same process but instead deploy a Windows 11 Gen 2 VM with Trusted Launch security, then customise and capture the specialised image to the Azure Compute Gallery, subsequent VMs fail to deploy from the image. Essentially, the only thing that changes in the Terraform snippet above is the reference to the storage_image_reference. The error thrown is something like this:

Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="The provided gallery image only supports the creation of VMs and VM Scale Sets with 'TrustedLaunch' security type."

  with azurerm_virtual_machine.windows,
  on user-script.tf line 80, in resource "azurerm_virtual_machine" "windows":
  80: resource "azurerm_virtual_machine" "windows" {

I do not believe the azurerm_virtual_machine resource type supports (or will ever support) the "Trusted Launch" security options, hence our failure.

It seems you cannot change the VM security type once it has been deployed, so instead, you would need to start from scratch using this method. Capturing an image of a VM retains the security type. Of course (and as pointed out), the azurerm_virtual_machine resource type is now deprecated, and the Trusted Launch security type will only ever become more widespread, so you are potentially painting yourself into a corner.

When generalising a Gen 2 VM that uses the Trusted Launch security type, I can use some Terraform similar to:

resource "azurerm_windows_virtual_machine" "windows" {
  admin_password            = "Password1234!"
  admin_username            = "testadmin"
  name                      = "testingvm"
  resource_group_name       = "${data.azurerm_resource_group.main.name}"
  location                  = "${data.azurerm_resource_group.main.location}"

  size                      = "Standard_B2s"
  network_interface_ids     = [azurerm_network_interface.winnic.id]
  secure_boot_enabled       = true
  vtpm_enabled              = true

  source_image_id           = "/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx/resourceGroups/myComputeGallery_RG/providers/Microsoft.Compute/galleries/myComputeGallery/images/Win11_Gen2_TurstedLaunch_Generalised"

  identity {
    type                    = "SystemAssigned"
  }

  os_disk {
    name                    = "${var.prefix}-osdisk"
    caching                 = "ReadWrite"
    storage_account_type    = "Standard_LRS"
  }

  depends_on = [
    azurerm_network_interface.winnic,
  ]
}

This uses the newer azurerm_windows_virtual_machine resource type, and we can specify the secure_boot_enabled and vtpm_enabled parameters to signify a Trusted Launch security VM (although these settings are independent within Azure - you can have a Trusted Launch VM without either Secure Boot or TPM enabled).

However, when switching to use a specialised image in the same Terraform snippet, we get another failure:

Error: creating Windows Virtual Machine: (Name "testingvm" / Resource Group "apr-0ymlynte2ggae"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="Parameter 'osProfile' is not allowed." Target="osProfile"

  with azurerm_windows_virtual_machine.windows,
  on user-script.tf line 80, in resource "azurerm_windows_virtual_machine" "windows":
  80: resource "azurerm_windows_virtual_machine" "windows" {

This is, of course, what @woter1832 initially reported above.

When deploying a VM from a specialised image in the portal, the Admin username and password fields are greyed out. However, we can't remove the admin_username and admin_password parameters from the Terraform as they are a requirement by the azurerm_windows_virtual_machine resource type. I'm unsure if this is the cause of the issue in this case. Maybe it's trying to change something in the OS profile that cannot be changed (hence the error).

Whatever, this is super frustrating as Gen 2 VMs using the Trusted Launch security type can be deployed from specialised images via the Azure portal and all other Azure command line options.

soumilk-LT commented 9 months ago

This is a HUGE problem !!!

The Simple Use Case is: I need to create a VM machine (or VMSS ) using a Specialised image using Trusted launch upon Spot priority. I am listing down the issues we are facing while automating the Azure Via Terraform.

  1. The priority and secure_boot_enabled attributes are only supported in the new azurerm_windows_virtual_machine or azurerm_linux_virtual_machine BUT I cant use the specialized image with those.

  2. The azurerm_virtual_machine resource type supports specialized images but it do not have option to set priority or secure_boot_enabled.

Due to the above problems, we are incurring loss because the automation cannot be implemented properly. We use Terraform for all the clouds and only Azure provider has such limitations. We need to create it manually everytime (via console or CLI).

I have been following this thread for a long time now and still no progress, its Super Frustrating to see such stupid limitations when Terraform providers for AWS and GCP is highly matured. PLEASEE fix this ASAP.

agyss commented 7 months ago

While this IMHO is a must have, I use the following workaround:

resource "terraform_data" "vm" {
  triggers_replace = [
    local.vm_name,
    "${var.dedicated_host_id != "" ? "--host ${var.dedicated_host_id}" : ""}",
    data.azurerm_resource_group.main.name,
    var.source_image_id,
    var.admin_password,
    data.azurerm_subnet.subnet.id,
    var.region
  ]

  input = {
    name            = local.vm_name
    host_id_section = "${var.dedicated_host_id != "" ? "--host ${var.dedicated_host_id}" : ""}"
    group           = data.azurerm_resource_group.main.name
    image           = var.source_image_id
    adminpw         = var.admin_password
    subnetid        = data.azurerm_subnet.subnet.id
    location        = var.region
  }
  provisioner "local-exec" {
    when    = create
    command = "az vm create -g ${self.input.group} -n ${self.input.name} --location \"${self.input.location}\" --image ${self.input.image} --specialized --admin-password ${self.input.adminpw} --size ${var.vm_size} --computer-name ${var.vm_name} --subnet ${self.input.subnetid} --enable-secure-boot --public-ip-address \"\" --nsg \"\" --enable-vtpm --os-disk-size-gb 256 --storage-sku Premium_LRS --zone 1 --os-disk-delete-option Delete --nic-delete-option Delete --security-type TrustedLaunch ${self.input.host_id_section}"
  }

  provisioner "local-exec" {
    when    = destroy
    command = "az vm delete -g ${self.input.group} -n ${self.input.name} --yes"
  }
}

The main 'problem' with this approach is that the subscription must be set correctly with 'az account set subscription' to where the resource should be created but this command could be added.

nathanblair commented 7 months ago

Creating a generalized image isn't possible for all virtual machine image definitions. There should be marked support of the azure_virtual_machine resource until the {windows|linux}_virtual_machine matures enough to support the specialized image deployment use case.

Bjarki2330 commented 6 months ago

Creating a generalized image isn't possible for all virtual machine image definitions. There should be marked support of the azure_virtual_machine resource until the {windows|linux}_virtual_machine matures enough to support the specialized image deployment use case.

I second this. I need to recreate three virtual machines for an important workload and want to use a specialized image with the windows/linux resource and this is driving me insane.

joaocc commented 4 months ago

Hi. Any news regarding this issue? Thanks