diff --git a/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.cs b/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.cs index ce6c8579f23d..6347327443f9 100644 --- a/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.cs +++ b/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.cs @@ -37,5 +37,12 @@ public void TestVirtualMachineProfileWithoutAUC() { TestRunner.RunTestScript("Test-VirtualMachineProfileWithoutAUC"); } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void TestAddAzVMDataDiskWithSecurityEncryption() + { + TestRunner.RunTestScript("Test-AddAzVMDataDiskWithSecurityEncryption"); + } } } diff --git a/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.ps1 b/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.ps1 index 73718922ab47..caf7f56ac13e 100644 --- a/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.ps1 +++ b/src/Compute/Compute.Test/ScenarioTests/VirtualMachineProfileTests.ps1 @@ -446,3 +446,47 @@ function Test-VirtualMachineProfileWithoutAUC Assert-False {$p.OSProfile.WindowsConfiguration.ProvisionVMAgent}; } + +<# +.SYNOPSIS +Test Add-AzVMDataDisk with SecurityEncryptionType and SecureVMDiskEncryptionSet for Confidential VM data disk encryption +#> +function Test-AddAzVMDataDiskWithSecurityEncryption +{ + $vmsize = 'Standard_A2'; + $vmname = 'pstestvm' + ((Get-Random) % 10000); + $p = New-AzVMConfig -VMName $vmname -VMSize $vmsize; + + # Storage + $stoname = 'hpfteststo' + ((Get-Random) % 10000); + $osDiskVhdUri = "https://$stoname.blob.core.windows.net/test/os.vhd"; + + $p = Set-AzVMOSDisk -VM $p -Name 'osDisk' -VhdUri $osDiskVhdUri -Caching 'ReadWrite' -CreateOption Empty; + + # Test adding a managed data disk with SecurityEncryptionType only + $managedDataDiskId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rggroup/providers/Microsoft.Compute/disks/testConfidentialDataDisk"; + $securityEncryptionType = "DiskWithVMGuestState"; + + $p = Add-AzVMDataDisk -VM $p -Name 'testConfidentialDataDisk' -Lun 0 -CreateOption Attach ` + -ManagedDiskId $managedDataDiskId -StorageAccountType 'Premium_LRS' ` + -SecurityEncryptionType $securityEncryptionType; + + Assert-AreEqual $managedDataDiskId $p.StorageProfile.DataDisks[0].ManagedDisk.Id; + Assert-AreEqual 'Premium_LRS' $p.StorageProfile.DataDisks[0].ManagedDisk.StorageAccountType; + Assert-AreEqual $securityEncryptionType $p.StorageProfile.DataDisks[0].ManagedDisk.SecurityProfile.SecurityEncryptionType; + Assert-Null $p.StorageProfile.DataDisks[0].ManagedDisk.SecurityProfile.DiskEncryptionSet; + + # Test adding a managed data disk with both SecurityEncryptionType and SecureVMDiskEncryptionSet + $managedDataDisk2Id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rggroup/providers/Microsoft.Compute/disks/testConfidentialDataDisk2"; + $secureVMDiskEncryptionSetId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rggroup/providers/Microsoft.Compute/diskEncryptionSets/testDES"; + + $p = Add-AzVMDataDisk -VM $p -Name 'testConfidentialDataDisk2' -Lun 1 -CreateOption Attach ` + -ManagedDiskId $managedDataDisk2Id -StorageAccountType 'Premium_LRS' ` + -SecurityEncryptionType $securityEncryptionType ` + -SecureVMDiskEncryptionSet $secureVMDiskEncryptionSetId; + + Assert-AreEqual $managedDataDisk2Id $p.StorageProfile.DataDisks[1].ManagedDisk.Id; + Assert-AreEqual 'Premium_LRS' $p.StorageProfile.DataDisks[1].ManagedDisk.StorageAccountType; + Assert-AreEqual $securityEncryptionType $p.StorageProfile.DataDisks[1].ManagedDisk.SecurityProfile.SecurityEncryptionType; + Assert-AreEqual $secureVMDiskEncryptionSetId $p.StorageProfile.DataDisks[1].ManagedDisk.SecurityProfile.DiskEncryptionSet.Id; +} diff --git a/src/Compute/Compute/ChangeLog.md b/src/Compute/Compute/ChangeLog.md index 14e253d71429..3bc4798b2dce 100644 --- a/src/Compute/Compute/ChangeLog.md +++ b/src/Compute/Compute/ChangeLog.md @@ -20,6 +20,7 @@ --> ## Upcoming Release +* Added `-SecurityEncryptionType` and `-SecureVMDiskEncryptionSet` parameters to `Add-AzVMDataDisk` cmdlet to support Confidential VM (CVM) data disk encryption. This enables binding data disk encryption keys to the VM's TPM (Trusted Platform Module) for end-to-end confidential computing protection. ## Version 11.4.0 * Added `-DiskIOPSReadWrite` and `-DiskMBpsReadWrite` parameters to `Add-AzVMDataDisk` cmdlet diff --git a/src/Compute/Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs b/src/Compute/Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs index 898cb42698b4..d5c5e332925c 100644 --- a/src/Compute/Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs +++ b/src/Compute/Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs @@ -164,6 +164,21 @@ public class AddAzureVMDataDiskCommand : ComputeClientBaseCmdlet HelpMessage = "Specifies the bandwidth in MB per second for the managed disk when StorageAccountType is UltraSSD_LRS or PremiumV2_LRS.")] public long? DiskMBpsReadWrite { get; set; } + [Parameter( + ParameterSetName = VmManagedDiskParameterSet, + Mandatory = false, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Sets the SecurityEncryptionType value on the managed disk of the data disk. Possible values include: DiskWithVMGuestState, VMGuestStateOnly, NonPersistedTPM. This parameter can only be used with managed disks.")] + [PSArgumentCompleter("DiskWithVMGuestState", "VMGuestStateOnly", "NonPersistedTPM")] + public string SecurityEncryptionType { get; set; } + + [Parameter( + ParameterSetName = VmManagedDiskParameterSet, + Mandatory = false, + ValueFromPipelineByPropertyName = true, + HelpMessage = "ARM Resource ID for the Disk Encryption Set to use for enabling encryption at rest with confidential disk encryption for the managed data disk. This parameter can only be used with managed disks. It is recommended to set SecurityEncryptionType to DiskWithVMGuestState when using this parameter.")] + public string SecureVMDiskEncryptionSet { get; set; } + public override void ExecuteCmdlet() { if (this.ParameterSetName.Equals(VmNormalDiskParameterSet)) @@ -230,7 +245,7 @@ public override void ExecuteCmdlet() storageProfile.DataDisks = new List(); } - storageProfile.DataDisks.Add(new DataDisk + var managedDataDisk = new DataDisk { Name = this.Name, Caching = this.Caching, @@ -246,7 +261,33 @@ public override void ExecuteCmdlet() }, DiskIOPSReadWrite = this.DiskIOPSReadWrite, DiskMBpsReadWrite = this.DiskMBpsReadWrite - }); + }; + + if (this.IsParameterBound(c => c.SecurityEncryptionType) || this.IsParameterBound(c => c.SecureVMDiskEncryptionSet)) + { + if (managedDataDisk.ManagedDisk == null) + { + managedDataDisk.ManagedDisk = new ManagedDiskParameters(); + } + if (managedDataDisk.ManagedDisk.SecurityProfile == null) + { + managedDataDisk.ManagedDisk.SecurityProfile = new VMDiskSecurityProfile(); + } + if (this.IsParameterBound(c => c.SecurityEncryptionType)) + { + managedDataDisk.ManagedDisk.SecurityProfile.SecurityEncryptionType = this.SecurityEncryptionType; + } + if (this.IsParameterBound(c => c.SecureVMDiskEncryptionSet)) + { + if (managedDataDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet == null) + { + managedDataDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet = new DiskEncryptionSetParameters(); + } + managedDataDisk.ManagedDisk.SecurityProfile.DiskEncryptionSet.Id = this.SecureVMDiskEncryptionSet; + } + } + + storageProfile.DataDisks.Add(managedDataDisk); this.VM.StorageProfile = storageProfile; diff --git a/src/Compute/Compute/help/Add-AzVMDataDisk.md b/src/Compute/Compute/help/Add-AzVMDataDisk.md index 0d164c023c7f..a3df6cb669bf 100644 --- a/src/Compute/Compute/help/Add-AzVMDataDisk.md +++ b/src/Compute/Compute/help/Add-AzVMDataDisk.md @@ -28,6 +28,7 @@ Add-AzVMDataDisk [-VM] [[-Name] ] [[-Caching] ] [-Lun] [-CreateOption] [[-ManagedDiskId] ] [[-StorageAccountType] ] [-DiskEncryptionSetId ] [-WriteAccelerator] [-DeleteOption ] [-SourceResourceId ] [-DiskIOPSReadWrite ] [-DiskMBpsReadWrite ] + [-SecurityEncryptionType ] [-SecureVMDiskEncryptionSet ] [-DefaultProfile ] [] ``` @@ -108,6 +109,19 @@ The command assigns a name and size to the virtual machine. The second command adds an UltraSSD data disk with custom IOPS (Input/Output Operations Per Second) set to 5000 and throughput set to 200 MB per second. These parameters allow fine-tuning of disk performance for UltraSSD_LRS and PremiumV2_LRS storage account types during implicit disk creation. +### Example 6: Add a confidential data disk with SecurityEncryptionType +```powershell +$VirtualMachine = New-AzVMConfig -VMName "VirtualMachine07" -VMSize "Standard_DC2as_v5" +$managedDiskId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Compute/disks/myDataDisk" +$VirtualMachine = Add-AzVMDataDisk -VM $VirtualMachine -Name "ConfidentialDataDisk1" -Lun 0 -CreateOption 'Attach' -ManagedDiskId $managedDiskId -StorageAccountType 'Premium_LRS' -SecurityEncryptionType 'DiskWithVMGuestState' -SecureVMDiskEncryptionSet "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Compute/diskEncryptionSets/myDES" +``` + +The first command creates a virtual machine object and stores it in the $VirtualMachine variable. +The command assigns a name and size to the virtual machine. +The second command adds a confidential data disk encrypted with the VMGuest state using a customer-managed key (CMK) via a Disk Encryption Set (DES). +The SecurityEncryptionType parameter set to 'DiskWithVMGuestState' enables confidential disk encryption that binds the disk encryption keys to the VM's TPM (Trusted Platform Module). +The SecureVMDiskEncryptionSet parameter specifies the ARM resource ID of the Disk Encryption Set created with the ConfidentialVmEncryptedWithCustomerKey encryption type. It is recommended to use this together with SecurityEncryptionType set to 'DiskWithVMGuestState'. + ## PARAMETERS ### -Caching @@ -392,6 +406,37 @@ Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` +### -SecurityEncryptionType +Sets the SecurityEncryptionType value on the managed disk of the data disk. Possible values include: DiskWithVMGuestState, VMGuestStateOnly, NonPersistedTPM. This parameter can only be used with managed disks. + +```yaml +Type: System.String +Parameter Sets: VmManagedDiskParameterSetName +Aliases: +Accepted values: DiskWithVMGuestState, VMGuestStateOnly, NonPersistedTPM + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SecureVMDiskEncryptionSet +ARM Resource ID for the Disk Encryption Set (DES) to use for enabling confidential disk encryption for the managed data disk. This parameter can only be used with managed disks. It is recommended to set SecurityEncryptionType to DiskWithVMGuestState when using this parameter. + +```yaml +Type: System.String +Parameter Sets: VmManagedDiskParameterSetName +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).