Skip to content

Commit

Permalink
feat: r/vsphere_virtual_machine add support for vTPM
Browse files Browse the repository at this point in the history
Added Support for vTPM on creation and clone of virtual machine.

Signed-off-by: Jared Burns <jared.burns@broadcom.com>
  • Loading branch information
burnsjared0415 committed Oct 8, 2024
1 parent 925fc60 commit d28111d
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ DOCUMENTATION:
- `resource/vsphere_resource_pool`: Updates to include steps to create resource pool on standalone ESXi hosts.
[#2264](https://github.com/hashicorp/terraform-provider-vsphere/pull/2264)

FEATURES:

- `resource/vsphere_virtual_machine`: Adds ability to add `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 `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.2 (September 16, 2024)

BUG FIX:
Expand Down
15 changes: 15 additions & 0 deletions vsphere/data_source_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
78 changes: 78 additions & 0 deletions vsphere/resource_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
Expand Down Expand Up @@ -594,6 +611,16 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
d.Set("power_state", "suspended")
}

// Check for the presence of a virtual Trusted Platform Module (TPM) device.
var isVTPMPresent bool
for _, dev := range vprops.Config.Hardware.Device {
if _, ok := dev.(*types.VirtualTPM); ok {
isVTPMPresent = true
break
}
}
_ = d.Set("vtpm_present", isVTPMPresent)

log.Printf("[DEBUG] %s: Read complete", resourceVSphereVirtualMachineIDString(d))
return nil
}
Expand Down Expand Up @@ -708,6 +735,19 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{
if spec.DeviceChange, err = applyVirtualDevices(d, client, devices); err != nil {
return err
}

if d.HasChange("vtpm") {
// Add vTPM device
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)
Expand Down Expand Up @@ -1366,6 +1406,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 {
Expand Down Expand Up @@ -2024,3 +2075,30 @@ func NewOvfHelperParamsFromVMResource(d *schema.ResourceData) *ovfdeploy.OvfHelp
}
return ovfParams
}

func configureVTPM(ctx context.Context, vm *object.VirtualMachine) error {
spec := types.VirtualMachineConfigSpec{
DeviceChange: []types.BaseVirtualDeviceConfigSpec{
&types.VirtualDeviceConfigSpec{
Operation: types.VirtualDeviceConfigSpecOperationAdd,
Device: &types.VirtualTPM{
VirtualDevice: types.VirtualDevice{
Key: -1,
},
},
},
},
}

task, err := vm.Reconfigure(ctx, spec)
if err != nil {
return fmt.Errorf("error reconfiguring VM to add vTPM: %s", err)
}

err = task.Wait(ctx)
if err != nil {
return fmt.Errorf("error waiting for vTPM reconfiguration task: %s", err)
}

return nil
}
1 change: 1 addition & 0 deletions website/docs/d/virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions website/docs/r/virtual_machine.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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 Platfrom Module

When building or cloning from template, there is a additional option to deploy virtual machine with vTPM hardware. This will only work on windows based machines.

**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.
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit d28111d

Please sign in to comment.