terraform-provider-vsphere icon indicating copy to clipboard operation
terraform-provider-vsphere copied to clipboard

Provider defaults to `BIOS` firmware when cloning from `content_library_item`

Open brunobenchimol opened this issue 3 years ago • 14 comments

Terraform Version

v1.0.9

vSphere Provider Version

vsphere 2.0.2

Affected Resource(s)

vsphere_content_library_item

Terraform Configuration Files

resource "vsphere_virtual_machine" "vm01" {
  name             = "${var.vm_prefix_name}-${resource.random_string.random.result}-01"

  resource_pool_id = data.vsphere_resource_pool.pool.id
  datastore_id     = data.vsphere_datastore.datastore.id

  num_cpus = 2
  memory   = 4096

  # works for resource: vsphere_virtual_machine.template
  #guest_id = data.vsphere_virtual_machine.template.guest_id
  #firmware = data.vsphere_virtual_machine.template.firmware

  # cant get firmware from content library - must set manually - need bugfix?
  firmware = "efi"

  network_interface {
    network_id = data.vsphere_network.network.id
  }

  disk {
    label = "disk0"
    size  = 60
  }

  clone {
    # Choose library or template
    #template_uuid = "${data.vsphere_virtual_machine.template.id}"
    template_uuid = "${data.vsphere_content_library_item.library_item.id}"
 }
}

Debug Output

Panic Output

Expected Behavior

VM deployed with same configuration from library no change on firmware, set the same as content library

Actual Behavior

Terraform timeouts and VM boots up with: Operating System not found firmware set to BIOS

Steps to Reproduce

terraform apply

Important Factoids

Only happens when cloning/deploying from content_library_item machine/template/ova/ovf that firmware and OS was installed as EFI. Does not happen when BIOS firmware is used/installed.

References

Facing same bug as issue #328 (https://github.com/hashicorp/terraform-provider-vsphere/issues/328). But affects only content_library_item instead of vsphere_virtual_machine.template

  • #0000

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

brunobenchimol avatar Oct 19 '21 15:10 brunobenchimol

@brunobenchimol can you provide which version of vSphere is in use in the environment?

In the meantime, I can confirm that there was an issue in 7.0.0 and 7.0.1 where cloning an OVF from the content library would revert any efi-secure or efi based OVF Templates to bios. I reported the issue to our engineering and it was resolved in 7.0.2 (7.0 Update 2)

Ryan

tenthirtyam avatar Oct 24 '21 15:10 tenthirtyam

@brunobenchimol can you provide which version of vSphere is in use in the environment?

In the meantime, I can confirm that there was an issue in 7.0.0 and 7.0.1 where cloning an OVF from the content library would revert any efi-secure or efi based OVF Templates to bios. I reported the issue to our engineering and it was resolved in 7.0.2 (7.0 Update 2)

Ryan

Hello,

Sure @tenthirtyam.

I am running the following versions:

vCenter Server Version: 7.0.3 Build: 18700403

Hypervisor Version: VMware ESXi, 7.0.1 Build: 17551050

brunobenchimol avatar Oct 24 '21 20:10 brunobenchimol

Thanks for the update @brunobenchimol. I'd be happy to test your example in my testbed early this week as see if I can confirm a reproduction.

Ryan

tenthirtyam avatar Oct 24 '21 21:10 tenthirtyam

@brunobenchimol - can you share a redacted version of the configuration files in a Gist?

Ryan

tenthirtyam avatar Oct 25 '21 13:10 tenthirtyam

@brunobenchimol - I took some time to test the scenario this morning based on a Ubuntu 20.04 LTS image pushed to a content library as efi-secure from Packer.

Basic Terraform Configuration

terraform {
  required_providers {
    vsphere = {
      source  = "hashicorp/vsphere"
      version = ">= 2.0.2"
    }
  }
  required_version = ">= 1.0.8"
}

provider "vsphere" {
  vsphere_server       = "m01-vc01.rainpole.io"
  user                 = "[email protected]"
  password             = "VMware1!"
  allow_unverified_ssl = true
}

data "vsphere_datacenter" "datacenter" {
  name = "m01-dc01"
}

data "vsphere_network" "network" {
  name          = "DHCP"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_compute_cluster" "cluster" {
  name          = "m01-cl01"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_resource_pool" "pool" {
  name          = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources")
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_datastore" "datastore" {
  name          = "local-ssd-01"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}
data "vsphere_content_library" "content_library" {
  name = "m01-lib01"
}

data "vsphere_content_library_item" "content_library_item" {
  name       = "linux-ubuntu-server-20-04-lts"
  type       = "ovf"
  library_id = data.vsphere_content_library.content_library.id
}

resource "vsphere_virtual_machine" "vm" {
  name                    = "ubuntu-test"
  datastore_id            = data.vsphere_datastore.datastore.id
  resource_pool_id        = data.vsphere_resource_pool.pool.id
  num_cpus                = 2
  memory                  = 4096
  network_interface {
    network_id = data.vsphere_network.network.id
  }
  disk {
    label = "disk0"
    size  = 60
  }
  clone {
    template_uuid = data.vsphere_content_library_item.content_library_item.id
  }
}

The result was identical to your report. The virtual machine was deployed with bios instead of efi (or efi-secure). The provider only supports either bios or efi but EFI secure boot can be enabled... more on that in a moment.

If I add the following to the resource, it will set the virtual machine to use efi - just as you described...

  firmware  = efi

However, since I'm using EFI with secure boot, I have to use the following to enable...

  firmware = efi
  efi_secure_boot_enabled = true

It seems that part of the cause is the following:

https://github.com/hashicorp/terraform-provider-vsphere/blob/ee62ff06fdcc8b0ca6185a03f02fbc0b1430d31f/vsphere/virtual_machine_config_structure.go#L277-L282

Since firmware is optional and has a default of bios, it is selected since there's not a capability to get the firmware and efi_secure_boot_enabled from the content_library_item as a data source.

It appears to be as designed, but I could argue that firmware should not be optional and that there should not be a default value of bios.

Ryan

tenthirtyam avatar Oct 25 '21 15:10 tenthirtyam

Related Issue: https://github.com/hashicorp/terraform-provider-vsphere/issues/1122

tenthirtyam avatar Oct 25 '21 15:10 tenthirtyam

Im glad you reached same result on your testbed. That's great.

Another interesting thing to point out: If you deploy a new virtual machine from content library using vCenter UI, it works perfectly, even though when you "Edit Virtual Machine Settings" > VM Options > Boot Options > Firmware. It says "BIOS (Recommended)"

I do not need to set firmware to EFI manually as when i do when deploying from Terraform. It seems some strange behavior as it should output the same error.

I believe that provider would mimic same result from vcenter itself or we are missing something. There is some "connection" missing out.

Since we're moving away from to BIOS to favor EFI as it can be more secure, we probably going to see many more EFI and EFI Secure VM than before.

If its reasonable you also could argue that works the same as "Virtual Machine Template". I also notice that we are using much more Content Library those days than regular templates to leverage the benefits of Content Library.

I hope that it can be helpful

Best regards

brunobenchimol avatar Oct 25 '21 18:10 brunobenchimol

Potential fix:

https://github.com/hashicorp/terraform-provider-vsphere/blob/ee62ff06fdcc8b0ca6185a03f02fbc0b1430d31f/vsphere/virtual_machine_config_structure.go#L277-L282

  • Change to the following:
 "firmware": { 
 	Type:         schema.TypeString, 
 	Required:     true, 
 	Description:  "The firmware to use on the virtual machine. Must be one of bios or efi.", 
 	ValidateFunc: validation.StringInSlice(virtualMachineFirmwareAllowedValues, false), 
  • Update the documentation.
  • Release note the breaking changes for users after provider upgrade if the firmware setting is not included in configurations.

Ryan

tenthirtyam avatar Oct 30 '21 20:10 tenthirtyam

Problem:

Since firmware is optional and has a default of bios, it is selected since there's not a capability to get the firmware and efi_secure_boot_enabled from the content_library_item as a data source.

Workaround:

  1. If using EFI images from the content library, add the following to the resource:
resource "vsphere_virtual_machine" "vm" {
  // ... other configuration ...
  firmware  = efi
  // ... other configuration ...
}
  1. If using EFI with secure boot for the images from the content library, add the following to the resource:
resource "vsphere_virtual_machine" "vm" {
  // ... other configuration ...
  firmware = efi
  efi_secure_boot_enabled = true
  // ... other configuration ...
}

Possible fixes listed earlier in thread.

Ryan

tenthirtyam avatar Nov 30 '21 22:11 tenthirtyam

@appilon - when the opportunity permits, can you review my prior comment and provide input on what you think would be the best approach. I'd be hesitant to remove the default as that could be a major breaking change.

Ryan

tenthirtyam avatar Jan 14 '22 04:01 tenthirtyam

Hi, I have similar problem with these options using clone. In my case, when I'm getting these values directly from the template, then I have:

╷
│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for module.vm1.vsphere_virtual_machine.vm[0] to include new values learned so far during apply, provider "registry.terraform.io/hashicorp/vsphere" produced an invalid new value for .firmware: was cty.StringVal("bios"), but now cty.StringVal("efi").
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for module.vm1.vsphere_virtual_machine.vm[0] to include new values learned so far during apply, provider "registry.terraform.io/hashicorp/vsphere" produced an invalid new value for .efi_secure_boot_enabled: was null, but now cty.True.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵

It is strange the template has valid data

> module.vm1.template[0].firmware
"efi"
> module.vm1.template[0].efi_secure_boot_enabled
true

But the weird thing is that the second terraform apply ends fine, without any errors!! Of course, when I have static values, as you in the workaround, the first run goes smoothly.

My config:

terraform -v            
Terraform v1.1.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/vsphere v2.0.2

and vSphere 7.0 Update 2d and the template built by Packer 1.7.8

pkaroluk avatar Jan 14 '22 23:01 pkaroluk

@pkaroluk are you using the virtual machine datasource to pull the values for the vm template?

tenthirtyam avatar Jan 15 '22 00:01 tenthirtyam

The VM template was built from scratch. When I created a sample VM from the template manually, it had correct VM Options.

pkaroluk avatar Jan 15 '22 00:01 pkaroluk

Adding to v3.0.0 milestone as this is will bring about a breaking change.

Ryan Johnson Staff II Solutions Architect | VMware, Inc.

tenthirtyam avatar Feb 23 '22 21:02 tenthirtyam