简体   繁体   中英

Is version mandatory while creating an Azure VM using terraform?

So I have been working with terraform since last 3 weeks and have been trying to use it to create self hosted GitHub Actions runners in our Azure account.

We have a shared windows VM image in Azure Compute Gallery that I'm planning to use as base image for the GA runner. I have noticed that these shared windows VM images do not generally have any versions attached to them they just have a publisher, offer and SKU attached.

I also verified by creating a new image from a VM to check if somebody missed attaching the version to the VM, but no shared images do not really have a version attached.

Yeah they do have versions but it is not attached as it is for Microsoft Platform Images.

Example of a shared image:

在此处输入图像描述

Now I found that in terraform, runners can be created by using both: azurerm_windows_virtual_machine and azurerm_virtual_machine resources.

I used both of them to test the runner creation, below are the terraform code used:

data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.cap_win_gold_image_gallery.name
  resource_group_name = "gi-rg"
}

resource "azurerm_virtual_machine" "win_runners_gold_image_based" {
  provider              = azurerm.og
  name                  = "ga-win-gold-1"
  location              = "East US"
  count                 = "1" # if I need to increase the number of VMs.
  resource_group_name   = data.azurerm_resource_group.dts_rg.name
  network_interface_ids = [azurerm_network_interface.azure_win_runner_gold_nic[count.index].id,]
  vm_size               = "Standard_D4ads_v5"

  delete_os_disk_on_termination = true
  delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = data.azurerm_shared_image.win19_gold_image.identifier[0].publisher
    offer     = data.azurerm_shared_image.win19_gold_image.identifier[0].offer
    sku       = data.azurerm_shared_image.win19_gold_image.identifier[0].sku
    # Here I get the error: Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter imageReference.version is invalid." Target="imageReference.version"
  }
  
  storage_os_disk {
    name              = "ga-win-gold-os-disk-1"
    caching           = "None"
    create_option     = "FromImage"
    managed_disk_type = "StandardSSD_LRS"
  }
  
  os_profile {
    computer_name  = "ga-win-gold-1"
    admin_username = "svc"
    admin_password = var.WINDOWS_ADMIN_PASS
  }
  
  os_profile_windows_config {
    enable_automatic_upgrades = true
    provision_vm_agent        = true
  }
  
  storage_data_disk {
    name              = "ga-win-gold-data-disk-1"
    caching           = "None"
    create_option     = "Empty"
    disk_size_gb      = var.disk_size_gb
    lun               = 0
    managed_disk_type = "StandardSSD_LRS"
  }
}

OR

data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.cap_win_gold_image_gallery.name
  resource_group_name = "gi-rg"
}

resource "azurerm_windows_virtual_machine" "azure_win_runner" {
  provider                          = azurerm.og
  name                              = "vm-github-actions-win-${count.index}"
  resource_group_name               = data.azurerm_resource_group.dts_rg.name
  location                          = "East US"
  size                              = var.windows-vm-size
  count                             = "${var.number_of_win_az_instances}"
  network_interface_ids             = [
    azurerm_network_interface.azure_win_runner_nic[count.index].id,
  ]
  computer_name                     = "vm-ga-win-${count.index}"
  admin_username                    = var.windows-admin-username
  admin_password                    = var.WINDOWS_ADMIN_PASS

  os_disk {
    name = "vm-github-actions-win-${count.index}-os-disk"
    caching              = "None"
    storage_account_type = "StandardSSD_LRS"
  }

  source_image_reference {
    publisher = data.azurerm_shared_image.win19_gold_image.identifier[0].publisher
    offer     = data.azurerm_shared_image.win19_gold_image.identifier[0].offer
    sku       = data.azurerm_shared_image.win19_gold_image.identifier[0].sku
    version   = data.azurerm_shared_image.win19_gold_image.identifier[0].version # says this object does not have a version attached to it.
    # or version = "latest" or any other correct version string will throw error at time of apply that such a version does not exist.
  }

  enable_automatic_updates = true
  provision_vm_agent       = true
}

If I'm using azurerm_virtual_machine then if I ignore the version in storage_image_reference I receive the error:

Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter imageReference.version is invalid." Target="imageReference.version"

And if I add the version then I receive the error

Error: Unsupported attribute. 
This object does not have an attribute named "version".

When using azurerm_windows_virtual_machine if I remove the version argument terraform complains that version is required and when provided a sting such as 1.0.0 or latest , while applying(terraform apply) it would complain that such a version does not exist.

And if I pull the version from data.azurerm_shared_image.cap_win19_gold_image it would complain that this object does not have a version.

I am confused as to how to use shared images for VM creation using terraform if version is mandatory yet if version is not available for azure shared images. Please advise on what am I missing?

Any help would be appreciated.

Thanks, Sekhar

It seems to get a version of the image you need to use another resource [1] and another data source [2]:

data "azurerm_image" "win19_gold_image" {
  name                = "Windows-2019_base"
  resource_group_name = "gi-rg"
}

resource "azurerm_shared_image_version" "win19_gold_image" {
  name                = "0.0.1"
  gallery_name        = data.azurerm_shared_image.win19_gold_image.gallery_name
  image_name          = data.azurerm_shared_image.win19_gold_image.name
  resource_group_name = data.azurerm_shared_image.win19_gold_image.resource_group_name
  location            = data.azurerm_shared_image.win19_gold_image.location
  managed_image_id    = data.azurerm_image.win19_gold_image.id
}

And then in the source_image_reference block in the azurerm_windows_virtual_machine resource:

  source_image_reference {
    publisher = data.azurerm_shared_image.win19_gold_image.identifier[0].publisher
    offer     = data.azurerm_shared_image.win19_gold_image.identifier[0].offer
    sku       = data.azurerm_shared_image.win19_gold_image.identifier[0].sku
    version   = azurerm_shared_image_version.win19_gold_image.name
  }

As it seems the name argument is actually the version of the image [3]:

name - (Required) The version number for this Image Version, such as 1.0.0. Changing this forces a new resource to be created.


[1] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/shared_image_version

[2] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/image

[3] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image_version#name

Hi All who come across this question,

I found the solution to my issue. All I had to do was define a azurerm_shared_image_version data and then use source_image_id in azurerm_windows_virtual_machine in place of source_image_reference{} block.

Below is what I did:

data "azurerm_shared_image_gallery" "win_gold_image_gallery" {
  provider            = azurerm.gi
  name                = "golden_image_gallery"
  resource_group_name = "gi-rg"
}

data "azurerm_shared_image" "win19_gold_image" {
  provider            = azurerm.gi
  name                = "Windows-2019_base"
  gallery_name        = data.azurerm_shared_image_gallery.win_gold_image_gallery.name
  resource_group_name = data.azurerm_shared_image_gallery.win_gold_image_gallery.resource_group_name
}

data "azurerm_shared_image_version" "win19_gold_image_version" {
  provider            = azurerm.gi
  name                = "latest" # "recent" is also a tag to use the most recent image version
  image_name          = data.azurerm_shared_image.win19_gold_image.name
  gallery_name        = data.azurerm_shared_image.win19_gold_image.gallery_name
  resource_group_name = data.azurerm_shared_image.win19_gold_image.resource_group_name
}

resource "azurerm_windows_virtual_machine" "azure_win_gi_runner" {
  provider                          = azurerm.dep
  name                              = "vm-github-actions-win-gi-${count.index}"
  resource_group_name               = data.azurerm_resource_group.dts_rg.name
  location                          = "East US"
  size                              = var.windows-vm-size
  count                             = "${var.number_of_win_gi_az_instances}"
  network_interface_ids             = [
    azurerm_network_interface.azure_win_gi_runner_nic[count.index].id,
  ]
  computer_name                     = "ga-win-gi-${count.index}"
  admin_username                    = var.windows-admin-username
  admin_password                    = var.WINDOWS_ADMIN_PASS

  os_disk {
    name = "vm-github-actions-win-gi-${count.index}-os-disk"
    caching              = "None"
    storage_account_type = "StandardSSD_LRS"
  }

  source_image_id = data.azurerm_shared_image_version.win19_gold_image_version.id 
# This is the thing I was missing.

  enable_automatic_updates = true
  provision_vm_agent       = true

  tags = {
    whichVM = var.gh_windows_runner
    environment = var.environment 
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM