Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compute] az disk create &az disk-encryption-set create: Support secure vm CMK #22780

Merged
merged 17 commits into from
Jun 29, 2022
Merged
3 changes: 3 additions & 0 deletions linter_exclusions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,9 @@ disk create:
source_storage_account_id:
rule_exclusions:
- option_length_too_long
secure_vm_disk_encryption_set:
rule_exclusions:
- option_length_too_long
disk update:
parameters:
network_access_policy:
Expand Down
5 changes: 3 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def load_arguments(self, _):
for scope in ['disk create', 'snapshot create']:
with self.argument_context(scope) as c:
c.argument('source', help='source to create the disk/snapshot from, including unmanaged blob uri, managed disk id or name, or snapshot id or name')
c.argument('secure_vm_disk_encryption_set', min_api='2021-08-01', help='Name or ID of disk encryption set created with ConfidentialVmEncryptedWithCustomerKey encryption type.')
# endregion

# region Disks
Expand Down Expand Up @@ -1435,8 +1436,8 @@ def load_arguments(self, _):
c.argument('disk_encryption_set_name', disk_encryption_set_name)
c.argument('key_url', help='URL pointing to a key or secret in KeyVault.')
c.argument('source_vault', help='Name or ID of the KeyVault containing the key or secret.')
c.argument('encryption_type', arg_type=get_enum_type(['EncryptionAtRestWithPlatformKey', 'EncryptionAtRestWithCustomerKey', 'EncryptionAtRestWithPlatformAndCustomerKeys']),
help='The type of key used to encrypt the data of the disk. EncryptionAtRestWithPlatformKey: Disk is encrypted at rest with Platform managed key. It is the default encryption type. EncryptionAtRestWithCustomerKey: Disk is encrypted at rest with Customer managed key that can be changed and revoked by a customer. EncryptionAtRestWithPlatformAndCustomerKeys: Disk is encrypted at rest with 2 layers of encryption. One of the keys is Customer managed and the other key is Platform managed.')
c.argument('encryption_type', arg_type=get_enum_type(['EncryptionAtRestWithPlatformKey', 'EncryptionAtRestWithCustomerKey', 'EncryptionAtRestWithPlatformAndCustomerKeys', 'ConfidentialVmEncryptedWithCustomerKey']),
zhoxing-ms marked this conversation as resolved.
Show resolved Hide resolved
help='The type of key used to encrypt the data of the disk. EncryptionAtRestWithPlatformKey: Disk is encrypted at rest with Platform managed key. It is the default encryption type. EncryptionAtRestWithCustomerKey: Disk is encrypted at rest with Customer managed key that can be changed and revoked by a customer. EncryptionAtRestWithPlatformAndCustomerKeys: Disk is encrypted at rest with 2 layers of encryption. One of the keys is Customer managed and the other key is Platform managed. ConfidentialVmEncryptedWithCustomerKey: An additional encryption type accepted for confidential VM. Disk is encrypted at rest with Customer managed key.')
cxznmhdcxz marked this conversation as resolved.
Show resolved Hide resolved
c.argument('location', validator=get_default_location_from_resource_group)
c.argument('tags', tags_type)
c.argument('enable_auto_key_rotation', arg_type=get_three_state_flag(), min_api='2020-12-01',
Expand Down
24 changes: 24 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,8 @@ def process_disk_create_namespace(cmd, namespace):
validate_tags(namespace)
validate_edge_zone(cmd, namespace)
_validate_gallery_image_reference(cmd, namespace)
_validate_secure_vm_disk_encryption_set(namespace)
_validate_hyper_v_generation(namespace)
if namespace.source:
usage_error = 'usage error: --source {SNAPSHOT | DISK | RESTOREPOINT} | ' \
'--source VHD_BLOB_URI [--source-storage-account-id ID]'
Expand All @@ -1760,6 +1762,28 @@ def process_disk_create_namespace(cmd, namespace):
raise ArgumentUsageError(usage_error)


def _validate_secure_vm_disk_encryption_set(namespace):
if 'secure_vm_disk_encryption_set' not in namespace:
return

if namespace.secure_vm_disk_encryption_set:
if not namespace.security_type or \
namespace.security_type.lower() != 'confidentialvm_diskencryptedwithcustomerkey':
raise ArgumentUsageError('usage error: --secure-vm-disk-encryption-set can only be specified only '
'when --security-type is set to ConfidentialVM_DiskEncryptedWithCustomerKey')

elif namespace.security_type and namespace.security_type.lower() == 'confidentialvm_diskencryptedwithcustomerkey':
raise ArgumentUsageError('usage error: --secure-vm-disk-encryption-set is mandatory when '
'--security-type is set to ConfidentialVM_DiskEncryptedWithCustomerKey')


def _validate_hyper_v_generation(namespace):
if namespace.security_type and (not namespace.hyper_v_generation or namespace.hyper_v_generation == 'V1'):
logger.warning(
'Enabling security features by using parameter "--security-type" requires UEFI support with Generation 2 '
'VMs, please set the parameter "--hyper-v-generation" to "V2" for enabling Generation 2 VM support.')


def process_snapshot_create_namespace(cmd, namespace):
from azure.core.exceptions import HttpResponseError
validate_tags(namespace)
Expand Down
14 changes: 11 additions & 3 deletions src/azure-cli/azure/cli/command_modules/vm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ class ExtensionUpdateLongRunningOperation(LongRunningOperation): # pylint: disa


# region Disks (Managed)
def create_managed_disk(cmd, resource_group_name, disk_name, location=None, # pylint: disable=too-many-locals, too-many-branches, too-many-statements
def create_managed_disk(cmd, resource_group_name, disk_name, location=None, # pylint: disable=too-many-locals, too-many-branches, too-many-statements, line-too-long
size_gb=None, sku='Premium_LRS', os_type=None,
source=None, for_upload=None, upload_size_bytes=None, # pylint: disable=unused-argument
# below are generated internally from 'source'
Expand All @@ -297,7 +297,8 @@ def create_managed_disk(cmd, resource_group_name, disk_name, location=None, # p
network_access_policy=None, disk_access=None, logical_sector_size=None,
tier=None, enable_bursting=None, edge_zone=None, security_type=None, support_hibernation=None,
public_network_access=None, accelerated_network=None, architecture=None,
data_access_auth_mode=None, gallery_image_reference_type=None):
data_access_auth_mode=None, gallery_image_reference_type=None,
secure_vm_disk_encryption_set=None):
from msrestazure.tools import resource_id, is_valid_resource_id
from azure.cli.core.commands.client_factory import get_subscription_id

Expand Down Expand Up @@ -374,6 +375,11 @@ def create_managed_disk(cmd, resource_group_name, disk_name, location=None, # p
subscription=get_subscription_id(cmd.cli_ctx), resource_group=resource_group_name,
namespace='Microsoft.Compute', type='diskAccesses', name=disk_access)

if secure_vm_disk_encryption_set is not None and not is_valid_resource_id(secure_vm_disk_encryption_set):
secure_vm_disk_encryption_set = resource_id(
subscription=get_subscription_id(cmd.cli_ctx), resource_group=resource_group_name,
namespace='Microsoft.Compute', type='diskEncryptionSets', name=secure_vm_disk_encryption_set)
zhoxing-ms marked this conversation as resolved.
Show resolved Hide resolved

encryption = None
if disk_encryption_set or encryption_type:
encryption = Encryption(type=encryption_type, disk_encryption_set_id=disk_encryption_set)
Expand Down Expand Up @@ -406,8 +412,10 @@ def create_managed_disk(cmd, resource_group_name, disk_name, location=None, # p
disk.bursting_enabled = enable_bursting
if edge_zone is not None:
disk.extended_location = edge_zone
if security_type is not None:
if security_type:
disk.security_profile = {'securityType': security_type}
if secure_vm_disk_encryption_set:
disk.security_profile['secure_vm_disk_encryption_set_id'] = secure_vm_disk_encryption_set
if support_hibernation is not None:
disk.supports_hibernation = support_hibernation
if public_network_access is not None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"anyOf": [
{
"allOf": [
{
"claim": "x-ms-attestation-type",
"equals": "sevsnpvm"
},
{
"claim": "x-ms-compliance-status",
"equals": "azure-compliant-cvm"
}
],
"authority": "https://sharedeus.eus.attest.azure.net/"
},
{
"allOf": [
{
"claim": "x-ms-attestation-type",
"equals": "sevsnpvm"
},
{
"claim": "x-ms-compliance-status",
"equals": "azure-compliant-cvm"
}
],
"authority": "https://sharedwus.wus.attest.azure.net/"
},
{
"allOf": [
{
"claim": "x-ms-attestation-type",
"equals": "sevsnpvm"
},
{
"claim": "x-ms-compliance-status",
"equals": "azure-compliant-cvm"
}
],
"authority": "https://sharedneu.neu.attest.azure.net/"
},
{
"allOf": [
{
"claim": "x-ms-attestation-type",
"equals": "sevsnpvm"
},
{
"claim": "x-ms-compliance-status",
"equals": "azure-compliant-cvm"
}
],
"authority": "https://sharedweu.weu.attest.azure.net/"
}
],
"version": "1.0.0"
}
Loading