diff --git a/CHANGELOG.md b/CHANGELOG.md index 600308d50..deb13bee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,21 @@ # +## 2.10.0 (Not Released) + +FEATURES: + +- `resource/vsphere_virtual_machine`: Adds ability to add a virtual Trusted Platform Module (`vtpm`) to virtual machine on creation or clone. + [#2279](https://github.com/hashicorp/terraform-provider-vsphere/pull/2279) +- `data/vsphere_virtual_machine`: Adds ability read the configuration of a virtual Trusted Platform Module (`vtpm`) on virtual machine; will return `true` or `false` based on the configuration. + [#2279](https://github.com/hashicorp/terraform-provider-vsphere/pull/2279) + ## 2.9.3 (October 8, 2024) BUG FIX: -- `r/vsphere_tag_category`: Updates resource not to `ForceNew` for cardinality. This will allow the `tag_category` to updated. +- `resource/vsphere_tag_category`: Updates resource not to `ForceNew` for cardinality. This will allow the `tag_category` to updated. ([#2263](https://github.com/hashicorp/terraform-provider-vsphere/pull/2263)) -- `r/vsphere_host`: Updates resource to check thumbprint of the ESXI host thumbprint before adding the host to a cluster or vCenter Server. +- `resource/vsphere_host`: Updates resource to check thumbprint of the ESXI host thumbprint before adding the host to a cluster or vCenter Server. ([#2266](https://github.com/hashicorp/terraform-provider-vsphere/pull/2266)) DOCUMENTATION: diff --git a/vsphere/data_source_vsphere_virtual_machine.go b/vsphere/data_source_vsphere_virtual_machine.go index 26db5b9b8..607d6e56e 100644 --- a/vsphere/data_source_vsphere_virtual_machine.go +++ b/vsphere/data_source_vsphere_virtual_machine.go @@ -165,6 +165,11 @@ func dataSourceVSphereVirtualMachine() *schema.Resource { Computed: true, Description: "Instance UUID of this virtual machine.", }, + "vtpm": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether a virtual Trusted Platform Module (TPM) device is present on the virtual machine.", + }, } // Merge the VirtualMachineConfig structure so that we can include the number of @@ -283,6 +288,16 @@ func dataSourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("error setting guest IP addresses: %s", err) } } + + var isVTPMPresent bool + for _, dev := range props.Config.Hardware.Device { + if _, ok := dev.(*types.VirtualTPM); ok { + isVTPMPresent = true + break + } + } + _ = d.Set("vtpm_present", isVTPMPresent) + log.Printf("[DEBUG] VM search for %q completed successfully (UUID %q)", name, props.Config.Uuid) return nil } diff --git a/vsphere/resource_vsphere_virtual_machine.go b/vsphere/resource_vsphere_virtual_machine.go index 2e59c5af7..c0b47f982 100644 --- a/vsphere/resource_vsphere_virtual_machine.go +++ b/vsphere/resource_vsphere_virtual_machine.go @@ -283,6 +283,23 @@ func resourceVSphereVirtualMachine() *schema.Resource { Computed: true, Description: "The power state of the virtual machine.", }, + "vtpm": { + Type: schema.TypeList, + Optional: true, + Description: "A specification for a virtual Trusted Platform Module (TPM) device on the virtual machine.", + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeString, + Optional: true, + Default: "2.0", + Description: "The version of the TPM device. Default is 2.0.", + ValidateFunc: validation.StringInSlice([]string{"1.2", "2.0"}, false), + }, + }, + }, + }, vSphereTagAttributeKey: tagsSchema(), customattribute.ConfigKey: customattribute.ConfigSchema(), } @@ -594,6 +611,24 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{}) d.Set("power_state", "suspended") } + // Set the virtual Trusted Platform Module device for the virtual machine. + var isVTPMPresent bool + for _, dev := range vprops.Config.Hardware.Device { + if _, ok := dev.(*types.VirtualTPM); ok { + isVTPMPresent = true + break + } + } + + if isVTPMPresent { + firmware := vprops.Config.Firmware + if isVTPMPresent && firmware != string(types.GuestOsDescriptorFirmwareTypeEfi) { + return errors.New("vtpm requires firmware to be set to efi") + } + } + + _ = d.Set("vtpm_present", isVTPMPresent) + log.Printf("[DEBUG] %s: Read complete", resourceVSphereVirtualMachineIDString(d)) return nil } @@ -708,6 +743,19 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ if spec.DeviceChange, err = applyVirtualDevices(d, client, devices); err != nil { return err } + + if d.HasChange("vtpm") { + + spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{ + Operation: types.VirtualDeviceConfigSpecOperationAdd, + Device: &types.VirtualTPM{ + VirtualDevice: types.VirtualDevice{ + Key: -1, + }, + }, + }) + } + // Only carry out the reconfigure if we actually have a change to process. cv := virtualmachine.GetHardwareVersionNumber(vprops.Config.Version) tv := d.Get("hardware_version").(int) @@ -1366,6 +1414,17 @@ func resourceVSphereVirtualMachineCreateBareStandard( VmPathName: fmt.Sprintf("[%s]", ds.Name()), } + if vtpms, ok := d.GetOk("vtpm"); ok && len(vtpms.([]interface{})) > 0 { + spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{ + Operation: types.VirtualDeviceConfigSpecOperationAdd, + Device: &types.VirtualTPM{ + VirtualDevice: types.VirtualDevice{ + Key: -1, + }, + }, + }) + } + timeout := meta.(*Client).timeout vm, err := virtualmachine.Create(client, fo, spec, pool, hs, timeout) if err != nil { diff --git a/website/docs/d/virtual_machine.html.markdown b/website/docs/d/virtual_machine.html.markdown index a7faf9fa1..e0599ecdb 100644 --- a/website/docs/d/virtual_machine.html.markdown +++ b/website/docs/d/virtual_machine.html.markdown @@ -159,6 +159,7 @@ The following attributes are exported: the VM is powered off, this value will be blank. * `guest_ip_addresses` - A list of IP addresses as reported by VMware Tools. * `instance_uuid` - The instance UUID of the virtual machine or template. +* `vtpm` - Indicates whether a virtual Trusted Platform Module (TPM) device is present on the virtual machine. ~> **NOTE:** Keep in mind when using the results of `scsi_type` and `network_interface_types`, that the `vsphere_virtual_machine` resource only diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index 7aaaee32f..31b18e795 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -1518,6 +1518,24 @@ When cloning from a template, there are additional requirements in both the reso You can use the [`vsphere_virtual_machine`][tf-vsphere-virtual-machine-ds] data source, which provides disk attributes, network interface types, SCSI bus types, and the guest ID of the source template, to return this information. See the section on [cloning and customization](#cloning-and-customization) for more information. +## Trusted Platform Module + +When creating a virtual machine or cloning one from a template, you have the option to add a virtual Trusted Platform Module device. Refer to the requirements in the VMware vSphere [product documentation](https://docs.vmware.com/en/VMware-vSphere/8.0/vsphere-security/GUID-6F811A7A-D58B-47B4-84B4-73391D55C268.html). + +**Example**: + +```hcl +resource "vsphere_virtual_machine" "vm" { + # ... other configuration ... + vtpm { + version = "2.0" + } + # ... other configuration ... +} +``` + +~> **NOTE:** Supported versions include 1.2 or 2.0. + ## Virtual Machine Migration The `vsphere_virtual_machine` resource supports live migration both on the host and storage level. You can migrate the virtual machine to another host, cluster, resource pool, or datastore. You can also migrate or pin a virtual disk to a specific datastore. @@ -1602,6 +1620,7 @@ The virtual machine will be rebooted if any of the following parameters are chan * `tools_upgrade_policy` * `vbs_enabled` * `vvtd_enabled` +* `vtpm` ## Attribute Reference