hashicorp / terraform-provider-vsphere

Terraform Provider for VMware vSphere
https://registry.terraform.io/providers/hashicorp/vsphere/
Mozilla Public License 2.0
612 stars 449 forks source link

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

Open brunobenchimol opened 2 years ago

brunobenchimol commented 2 years ago

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

Community Note

tenthirtyam commented 2 years ago

@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

brunobenchimol commented 2 years ago

@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

tenthirtyam commented 2 years ago

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 commented 2 years ago

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

Ryan

tenthirtyam commented 2 years ago

@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                 = "administrator@vsphere.local"
  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 commented 2 years ago

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

brunobenchimol commented 2 years ago

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

tenthirtyam commented 2 years ago

Potential fix:

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

Ryan

tenthirtyam commented 2 years ago

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 commented 2 years ago

@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

pkaroluk commented 2 years ago

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

tenthirtyam commented 2 years ago

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

pkaroluk commented 2 years ago

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

tenthirtyam commented 2 years ago

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

Ryan Johnson Staff II Solutions Architect | VMware, Inc.