Skip to content

Commit 8a499ff

Browse files
authored
[Compute] Add Managed Identity Support in Azure Disk Encryption for VMSS (#30657)
1 parent 2da376c commit 8a499ff

12 files changed

+14168
-4
lines changed

src/azure-cli/azure/cli/command_modules/vm/_help.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2568,6 +2568,9 @@
25682568
- name: Create a Debian11 VM scaleset with a user assigned identity.
25692569
text: >
25702570
az vmss create -n MyVmss -g rg1 --image Debian11 --assign-identity /subscriptions/99999999-1bf0-4dda-aec3-cb9272f09590/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID
2571+
- name: Create a vmss with user assigned identity and add encryption identity for Azure disk encryption
2572+
text: >
2573+
az vmss create -n MyVm -g rg1 --image Debian11 --assign-identity myID --encryption-identity /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID --orchestration-mode Uniform --lb-sku Standard
25712574
- name: Create a Debian11 VM scaleset with both system and user assigned identity.
25722575
text: >
25732576
az vmss create -n MyVmss -g rg1 --image Debian11 --assign-identity [system] /subscriptions/99999999-1bf0-4dda-aec3-cb9272f09590/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID
@@ -2685,6 +2688,9 @@
26852688
- name: encrypt a VM scale set using a key vault in the same resource group
26862689
text: >
26872690
az vmss encryption enable -g MyResourceGroup -n MyVmss --disk-encryption-keyvault MyVault
2691+
- name: Add support for using managed identity to authenticate to customer's keyvault for ADE operation
2692+
text: >
2693+
az vmss encryption enable --disk-encryption-keyvault MyVault --name MyVm --resource-group MyResourceGroup --encryption-identity EncryptionIdentity
26882694
- name: Encrypt a VMSS with managed disks. (autogenerated)
26892695
text: |
26902696
az vmss encryption enable --disk-encryption-keyvault MyVault --name MyVmss --resource-group MyResourceGroup --volume-type DATA

src/azure-cli/azure/cli/command_modules/vm/_params.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ def load_arguments(self, _):
473473
c.argument('enable_vtpm', enable_vtpm_type)
474474
c.argument('user_data', help='UserData for the VM. It can be passed in as file or string.', completer=FilesCompleter(), type=file_type, min_api='2021-03-01')
475475
c.argument('enable_hibernation', arg_type=get_three_state_flag(), min_api='2021-03-01', help='The flag that enable or disable hibernation capability on the VM.')
476-
c.argument('encryption_identity', help='Resource Id of the user managed identity which can be used for Azure disk encryption')
477476

478477
for scope in ['vm create', 'vm update']:
479478
with self.argument_context(scope) as c:
@@ -1192,8 +1191,13 @@ def load_arguments(self, _):
11921191
c.argument('key_encryption_key', help='Key vault key name or URL used to encrypt the disk encryption key.')
11931192
c.argument('key_encryption_keyvault', help='Name or ID of the key vault containing the key encryption key used to encrypt the disk encryption key. If missing, CLI will use `--disk-encryption-keyvault`.')
11941193

1195-
with self.argument_context('vm encryption enable') as c:
1196-
c.argument('encryption_identity', help='Resource Id of the user managed identity which can be used for Azure disk encryption')
1194+
for scope in ['vm create', 'vm encryption enable']:
1195+
with self.argument_context(scope) as c:
1196+
c.argument('encryption_identity', help='Resource Id of the user managed identity which can be used for Azure disk encryption', resource_type=ResourceType.MGMT_COMPUTE, min_api='2023-09-01')
1197+
1198+
for scope in ['vmss create', 'vmss encryption enable']:
1199+
with self.argument_context(scope) as c:
1200+
c.argument('encryption_identity', help='Resource Id of the user managed identity which can be used for Azure disk encryption', resource_type=ResourceType.MGMT_COMPUTE, min_api='2023-09-01')
11971201

11981202
for scope in ['vm extension', 'vmss extension']:
11991203
with self.argument_context(scope) as c:

src/azure-cli/azure/cli/command_modules/vm/custom.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3210,7 +3210,7 @@ def create_vmss(cmd, vmss_name, resource_group_name, image=None,
32103210
public_ip_address_type=None, storage_profile=None,
32113211
single_placement_group=None, custom_data=None, secrets=None, platform_fault_domain_count=None,
32123212
plan_name=None, plan_product=None, plan_publisher=None, plan_promotion_code=None, license_type=None,
3213-
assign_identity=None, identity_scope=None, identity_role=None,
3213+
assign_identity=None, identity_scope=None, identity_role=None, encryption_identity=None,
32143214
identity_role_id=None, zones=None, priority=None, eviction_policy=None,
32153215
application_security_groups=None, ultra_ssd_enabled=None,
32163216
ephemeral_os_disk=None, ephemeral_os_disk_placement=None,
@@ -3572,6 +3572,30 @@ def _get_public_ip_address_allocation(value, sku):
35723572
role_assignment_guid = str(_gen_guid())
35733573
master_template.add_resource(build_msi_role_assignment(vmss_name, vmss_id, identity_role_id,
35743574
role_assignment_guid, identity_scope, False))
3575+
if encryption_identity:
3576+
if 'identity' in vmss_resource and 'userAssignedIdentities' in vmss_resource['identity'] \
3577+
and encryption_identity.lower() in \
3578+
(k.lower() for k in vmss_resource['identity']['userAssignedIdentities'].keys()):
3579+
3580+
if 'virtualMachineProfile' not in vmss_resource['properties']:
3581+
vmss_resource['properties']['virtualMachineProfile'] = {}
3582+
if 'securityProfile' not in vmss_resource['properties']['virtualMachineProfile']:
3583+
vmss_resource['properties']['virtualMachineProfile']['securityProfile'] = {}
3584+
if 'encryptionIdentity' not in vmss_resource['properties']['virtualMachineProfile']['securityProfile']:
3585+
vmss_resource['properties']['virtualMachineProfile']['securityProfile']['encryptionIdentity'] = {}
3586+
3587+
vmss_securityProfile_EncryptionIdentity \
3588+
= vmss_resource['properties']['virtualMachineProfile']['securityProfile']['encryptionIdentity']
3589+
3590+
if 'userAssignedIdentityResourceId' not in vmss_securityProfile_EncryptionIdentity or \
3591+
vmss_securityProfile_EncryptionIdentity['userAssignedIdentityResourceId'] \
3592+
!= encryption_identity:
3593+
vmss_securityProfile_EncryptionIdentity['userAssignedIdentityResourceId'] = encryption_identity
3594+
vmss_resource['properties']['virtualMachineProfile']['securityProfile']['encryptionIdentity'] \
3595+
= vmss_securityProfile_EncryptionIdentity
3596+
else:
3597+
raise ArgumentUsageError("Encryption Identity should be an ARM Resource ID of one of the "
3598+
"user assigned identities associated to the resource")
35753599
else:
35763600
raise CLIError('usage error: --orchestration-mode (Uniform | Flexible)')
35773601

src/azure-cli/azure/cli/command_modules/vm/disk_encryption.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,41 @@ def updateVmEncryptionSetting(cmd, vm, resource_group_name, vm_name, encryption_
9292
return True
9393

9494

95+
def updateVmssEncryptionSetting(cmd, vmss, resource_group_name, vmss_name, encryption_identity):
96+
from azure.cli.core.azclierror import ArgumentUsageError
97+
if vmss.identity is None or vmss.identity.user_assigned_identities is None or encryption_identity.lower() not in \
98+
(k.lower() for k in vmss.identity.user_assigned_identities.keys()):
99+
raise ArgumentUsageError("Encryption Identity should be an ARM Resource ID of one of the "
100+
"user assigned identities associated to the resource")
101+
102+
VirtualMachineProfile, SecurityProfile, EncryptionIdentity \
103+
= cmd.get_models('VirtualMachineProfile', 'SecurityProfile', 'EncryptionIdentity')
104+
updateVmss = False
105+
106+
if vmss.virtual_machine_profile is None:
107+
vmss.virtual_machine_profile = VirtualMachineProfile()
108+
if vmss.virtual_machine_profile.security_profile is None:
109+
vmss.virtual_machine_profile.security_profile = SecurityProfile()
110+
if vmss.virtual_machine_profile.security_profile.encryption_identity is None:
111+
vmss.virtual_machine_profile.security_profile.encryption_identity = EncryptionIdentity()
112+
if vmss.virtual_machine_profile.security_profile.encryption_identity.user_assigned_identity_resource_id\
113+
is None or vmss.virtual_machine_profile.security_profile.encryption_identity\
114+
.user_assigned_identity_resource_id.lower() != encryption_identity:
115+
vmss.virtual_machine_profile.security_profile.encryption_identity.user_assigned_identity_resource_id \
116+
= encryption_identity
117+
updateVmss = True
118+
119+
if updateVmss:
120+
compute_client = _compute_client_factory(cmd.cli_ctx)
121+
updateEncryptionIdentity \
122+
= compute_client.virtual_machine_scale_sets.begin_create_or_update(resource_group_name, vmss_name, vmss)
123+
LongRunningOperation(cmd.cli_ctx)(updateEncryptionIdentity)
124+
result = updateEncryptionIdentity.result()
125+
return result is not None and result.provisioning_state == 'Succeeded'
126+
logger.info("No changes in identity")
127+
return True
128+
129+
95130
def isVersionSuppprtedForEncryptionIdentity(cmd):
96131
from azure.cli.core.profiles import ResourceType
97132
from knack.util import CLIError
@@ -436,8 +471,10 @@ def encrypt_vmss(cmd, resource_group_name, vmss_name, # pylint: disable=too-man
436471
key_encryption_key=None,
437472
key_encryption_algorithm='RSA-OAEP',
438473
volume_type=None,
474+
encryption_identity=None,
439475
force=False):
440476
from azure.mgmt.core.tools import parse_resource_id
477+
from knack.util import CLIError
441478

442479
# pylint: disable=no-member
443480
UpgradeMode, VirtualMachineScaleSetExtension, VirtualMachineScaleSetExtensionProfile = cmd.get_models(
@@ -459,6 +496,13 @@ def encrypt_vmss(cmd, resource_group_name, vmss_name, # pylint: disable=too-man
459496
if key_encryption_key:
460497
key_encryption_keyvault = key_encryption_keyvault or disk_encryption_keyvault
461498

499+
if encryption_identity:
500+
result = updateVmssEncryptionSetting(cmd, vmss, resource_group_name, vmss_name, encryption_identity)
501+
if result:
502+
logger.info("Encryption Identity successfully set in virtual machine scale set")
503+
else:
504+
raise CLIError("Failed to update encryption Identity to the VMSS")
505+
462506
# to avoid bad server errors, ensure the vault has the right configurations
463507
_verify_keyvault_good_for_encryption(cmd.cli_ctx, disk_encryption_keyvault, key_encryption_keyvault, vmss, force)
464508

0 commit comments

Comments
 (0)