Skip to content

Commit

Permalink
Adding #16908
Browse files Browse the repository at this point in the history
* \managed_disk: Add support for Confidential VM

* Fix test
  • Loading branch information
myc2h6o authored May 25, 2022
1 parent ee30790 commit ca6c359
Showing 3 changed files with 253 additions and 1 deletion.
60 changes: 60 additions & 0 deletions internal/services/compute/managed_disk_resource.go
Original file line number Diff line number Diff line change
@@ -181,6 +181,7 @@ func resourceManagedDisk() *pluginsdk.Resource {
// https://github.com/Azure/azure-rest-api-specs/issues/8132
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validate.DiskEncryptionSetID,
ConflictsWith: []string{"secure_vm_disk_encryption_set_id"},
},

"encryption_settings": encryptionSettingsSchema(),
@@ -228,6 +229,25 @@ func resourceManagedDisk() *pluginsdk.Resource {
ForceNew: true,
},

"secure_vm_disk_encryption_set_id": {
Type: pluginsdk.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validate.DiskEncryptionSetID,
ConflictsWith: []string{"disk_encryption_set_id"},
},

"security_type": {
Type: pluginsdk.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.DiskSecurityTypesConfidentialVMVMGuestStateOnlyEncryptedWithPlatformKey),
string(compute.DiskSecurityTypesConfidentialVMDiskEncryptedWithPlatformKey),
string(compute.DiskSecurityTypesConfidentialVMDiskEncryptedWithCustomerKey),
}, false),
},

"hyper_v_generation": {
Type: pluginsdk.TypeString,
Optional: true,
@@ -436,6 +456,36 @@ func resourceManagedDiskCreate(d *pluginsdk.ResourceData, meta interface{}) erro
}
}

securityType := d.Get("security_type").(string)
secureVMDiskEncryptionId := d.Get("secure_vm_disk_encryption_set_id")
if securityType != "" {
if d.Get("trusted_launch_enabled").(bool) {
return fmt.Errorf("`security_type` cannot be specified when `trusted_launch_enabled` is set to `true`")
}

switch createOption {
case compute.DiskCreateOptionFromImage:
case compute.DiskCreateOptionImport:
default:
return fmt.Errorf("`security_type` can only be specified when `create_option` is set to `FromImage` or `Import`")
}

if compute.DiskSecurityTypesConfidentialVMDiskEncryptedWithCustomerKey == compute.DiskSecurityTypes(securityType) && secureVMDiskEncryptionId == "" {
return fmt.Errorf("`secure_vm_disk_encryption_set_id` must be specified when `security_type` is set to `ConfidentialVM_DiskEncryptedWithCustomerKey`")
}

props.SecurityProfile = &compute.DiskSecurityProfile{
SecurityType: compute.DiskSecurityTypes(securityType),
}
}

if secureVMDiskEncryptionId != "" {
if compute.DiskSecurityTypesConfidentialVMDiskEncryptedWithCustomerKey != compute.DiskSecurityTypes(securityType) {
return fmt.Errorf("`secure_vm_disk_encryption_set_id` can only be specified when `security_type` is set to `ConfidentialVM_DiskEncryptedWithCustomerKey`")
}
props.SecurityProfile.SecureVMDiskEncryptionSetID = utils.String(secureVMDiskEncryptionId.(string))
}

if d.Get("on_demand_bursting_enabled").(bool) {
switch storageAccountType {
case string(compute.StorageAccountTypesPremiumLRS):
@@ -877,12 +927,22 @@ func resourceManagedDiskRead(d *pluginsdk.ResourceData, meta interface{}) error
}

trustedLaunchEnabled := false
securityType := ""
secureVMDiskEncryptionSetId := ""
if securityProfile := props.SecurityProfile; securityProfile != nil {
if securityProfile.SecurityType == compute.DiskSecurityTypesTrustedLaunch {
trustedLaunchEnabled = true
} else {
securityType = string(securityProfile.SecurityType)
}

if securityProfile.SecureVMDiskEncryptionSetID != nil {
secureVMDiskEncryptionSetId = *securityProfile.SecureVMDiskEncryptionSetID
}
}
d.Set("trusted_launch_enabled", trustedLaunchEnabled)
d.Set("security_type", securityType)
d.Set("secure_vm_disk_encryption_set_id", secureVMDiskEncryptionSetId)

onDemandBurstingEnabled := false
if props.BurstingEnabled != nil {
182 changes: 182 additions & 0 deletions internal/services/compute/managed_disk_resource_test.go
Original file line number Diff line number Diff line change
@@ -544,6 +544,36 @@ func TestAccManagedDisk_create_withTrustedLaunchEnabled(t *testing.T) {
})
}

func TestAccManagedDisk_create_withSecurityType(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.create_withSecurityType(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccManagedDisk_create_withSecureVMDiskEncryptionSetId(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.create_withSecureVMDiskEncryptionSetId(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccManagedDisk_update_withIOpsReadOnlyAndMBpsReadOnly(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}
@@ -1756,6 +1786,158 @@ resource "azurerm_managed_disk" "test" {
`, data.Locations.Primary, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (ManagedDiskResource) create_withSecurityType(data acceptance.TestData) string {
// Confidential VM has limited region support
data.Locations.Primary = "northeurope"
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
data "azurerm_platform_image" "test" {
location = "%s"
publisher = "Canonical"
offer = "0001-com-ubuntu-confidential-vm-focal"
sku = "20_04-lts-cvm"
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_managed_disk" "test" {
name = "acctestd-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
os_type = "Linux"
hyper_v_generation = "V2"
create_option = "FromImage"
image_reference_id = data.azurerm_platform_image.test.id
storage_account_type = "Standard_LRS"
security_type = "ConfidentialVM_VMGuestStateOnlyEncryptedWithPlatformKey"
}
`, data.Locations.Primary, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (ManagedDiskResource) create_withSecureVMDiskEncryptionSetId(data acceptance.TestData) string {
// Confidential VM has limited region support
data.Locations.Primary = "northeurope"
return fmt.Sprintf(`
provider "azurerm" {
features {
key_vault {
recover_soft_deleted_key_vaults = false
purge_soft_delete_on_destroy = false
purge_soft_deleted_keys_on_destroy = false
}
}
}
data "azurerm_client_config" "current" {}
data "azurerm_platform_image" "test" {
location = "%[1]s"
publisher = "Canonical"
offer = "0001-com-ubuntu-confidential-vm-focal"
sku = "20_04-lts-cvm"
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[2]d"
location = "%[1]s"
}
resource "azurerm_key_vault" "test" {
name = "acctestkv%[3]s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku_name = "premium"
tenant_id = data.azurerm_client_config.current.tenant_id
enabled_for_disk_encryption = true
soft_delete_retention_days = 7
purge_protection_enabled = true
}
resource "azurerm_key_vault_access_policy" "service-principal" {
key_vault_id = azurerm_key_vault.test.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = [
"Create",
"Delete",
"Get",
"Purge",
"Update",
]
secret_permissions = [
"Get",
"Delete",
"Set",
]
}
resource "azurerm_key_vault_key" "test" {
name = "examplekey"
key_vault_id = azurerm_key_vault.test.id
key_type = "RSA-HSM"
key_size = 2048
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
depends_on = [azurerm_key_vault_access_policy.service-principal]
}
resource "azurerm_disk_encryption_set" "test" {
name = "acctestdes-%[2]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
key_vault_key_id = azurerm_key_vault_key.test.id
encryption_type = "ConfidentialVmEncryptedWithCustomerKey"
identity {
type = "SystemAssigned"
}
}
resource "azurerm_key_vault_access_policy" "disk-encryption" {
key_vault_id = azurerm_key_vault.test.id
key_permissions = [
"Get",
"WrapKey",
"UnwrapKey",
]
tenant_id = azurerm_disk_encryption_set.test.identity.0.tenant_id
object_id = azurerm_disk_encryption_set.test.identity.0.principal_id
}
resource "azurerm_managed_disk" "test" {
name = "acctestd-%[2]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
os_type = "Linux"
hyper_v_generation = "V2"
create_option = "FromImage"
image_reference_id = data.azurerm_platform_image.test.id
storage_account_type = "Standard_LRS"
security_type = "ConfidentialVM_DiskEncryptedWithCustomerKey"
secure_vm_disk_encryption_set_id = azurerm_disk_encryption_set.test.id
depends_on = [
azurerm_key_vault_access_policy.disk-encryption,
]
}
`, data.Locations.Primary, data.RandomInteger, data.RandomString)
}

func (ManagedDiskResource) create_withIOpsReadOnlyAndMBpsReadOnly(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
12 changes: 11 additions & 1 deletion website/docs/r/managed_disk.html.markdown
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ The following arguments are supported:

---

* `disk_encryption_set_id` - (Optional) The ID of a Disk Encryption Set which should be used to encrypt this Managed Disk.
* `disk_encryption_set_id` - (Optional) The ID of a Disk Encryption Set which should be used to encrypt this Managed Disk. Conflicts with `secure_vm_disk_encryption_set_id`.

~> **NOTE:** The Disk Encryption Set must have the `Reader` Role Assignment scoped on the Key Vault - in addition to an Access Policy to the Key Vault

@@ -143,6 +143,16 @@ The following arguments are supported:

-> **Note:** Trusted Launch can only be enabled when `create_option` is `FromImage` or `Import`.

* `security_type` - (Optional) Security Type of the Managed Disk when it is used for a Confidential VM. Possible values are `ConfidentialVM_VMGuestStateOnlyEncryptedWithPlatformKey`, `ConfidentialVM_DiskEncryptedWithPlatformKey` and `ConfidentialVM_DiskEncryptedWithCustomerKey`. Changing this forces a new resource to be created.

~> **NOTE:** `security_type` cannot be specified when `trusted_launch_enabled` is set to true.

~> **NOTE:** `secure_vm_disk_encryption_set_id` must be specified when `security_type` is set to `ConfidentialVM_DiskEncryptedWithCustomerKey`.

* `secure_vm_disk_encryption_set_id` - (Optional) The ID of the Disk Encryption Set which should be used to Encrypt this OS Disk when the Virtual Machine is a Confidential VM. Conflicts with `disk_encryption_set_id`. Changing this forces a new resource to be created.

~> **NOTE:** `secure_vm_disk_encryption_set_id` can only be specified when `security_type` is set to `ConfidentialVM_DiskEncryptedWithCustomerKey`.

* `on_demand_bursting_enabled` (Optional) Specifies if On-Demand Bursting is enabled for the Managed Disk. Defaults to `false`.

-> **Note:** Credit-Based Bursting is enabled by default on all eligible disks. More information on [Credit-Based and On-Demand Bursting can be found in the documentation](https://docs.microsoft.com/azure/virtual-machines/disk-bursting#disk-level-bursting).

0 comments on commit ca6c359

Please sign in to comment.