Encrypt OS and attached data disks in a Virtual Machine Scale Set with Azure PowerShell
The Azure PowerShell module is used to create and manage Azure resources from the PowerShell command line or in scripts. This article shows you how to use Azure PowerShell to create and encrypt a Virtual Machine Scale Set. For more information on applying Azure Disk Encryption to a Virtual Machine Scale Set, see Azure Disk Encryption for Virtual Machine Scale Sets.
Azure Cloud Shell
Azure hosts Azure Cloud Shell, an interactive shell environment that you can use through your browser. You can use either Bash or PowerShell with Cloud Shell to work with Azure services. You can use the Cloud Shell preinstalled commands to run the code in this article, without having to install anything on your local environment.
To start Azure Cloud Shell:
Option | Example/Link |
---|---|
Select Try It in the upper-right corner of a code or command block. Selecting Try It doesn't automatically copy the code or command to Cloud Shell. | |
Go to https://shell.azure.com, or select the Launch Cloud Shell button to open Cloud Shell in your browser. | |
Select the Cloud Shell button on the menu bar at the upper right in the Azure portal. |
To use Azure Cloud Shell:
Start Cloud Shell.
Select the Copy button on a code block (or command block) to copy the code or command.
Paste the code or command into the Cloud Shell session by selecting Ctrl+Shift+V on Windows and Linux, or by selecting Cmd+Shift+V on macOS.
Select Enter to run the code or command.
Create an Azure Key Vault enabled for disk encryption
Azure Key Vault can store keys, secrets, or passwords that allow you to securely implement them in your applications and services. Cryptographic keys are stored in Azure Key Vault using software-protection, or you can import or generate your keys in Hardware Security Modules (HSMs) certified to FIPS 140 validated standards. These cryptographic keys are used to encrypt and decrypt virtual disks attached to your VM. You retain control of these cryptographic keys and can audit their use.
Create a Key Vault with New-AzKeyVault. To allow the Key Vault to be used for disk encryption, set the EnabledForDiskEncryption parameter. The following example also defines variables for resource group name, Key Vault Name, and location. Provide your own unique Key Vault name:
$rgName="myResourceGroup"
$vaultName="myuniquekeyvault"
$location = "EastUS"
New-AzResourceGroup -Name $rgName -Location $location
New-AzKeyVault -VaultName $vaultName -ResourceGroupName $rgName -Location $location -EnabledForDiskEncryption
Use an existing Key Vault
This step is only required if you have an existing Key Vault that you wish to use with disk encryption. Skip this step if you created a Key Vault in the previous section.
You can enable an existing Key Vault in the same subscription and region as the scale set for disk encryption with Set-AzKeyVaultAccessPolicy. Define the name of your existing Key Vault in the $vaultName variable as follows:
$vaultName="myexistingkeyvault"
Set-AzKeyVaultAccessPolicy -VaultName $vaultName -EnabledForDiskEncryption
Create a scale set
Important
Starting November 2023, VM scale sets created using PowerShell and Azure CLI will default to Flexible Orchestration Mode if no orchestration mode is specified. For more information about this change and what actions you should take, go to Breaking Change for VMSS PowerShell/CLI Customers - Microsoft Community Hub
First, set an administrator username and password for the VM instances with Get-Credential:
$cred = Get-Credential
Now create a Virtual Machine Scale Set with New-AzVmss. To distribute traffic to the individual VM instances, a load balancer is also created. The load balancer includes rules to distribute traffic on TCP port 80, as well as allow remote desktop traffic on TCP port 3389 and PowerShell remoting on TCP port 5985:
$vmssName="myScaleSet"
New-AzVmss `
-ResourceGroupName $rgName `
-VMScaleSetName $vmssName `
-OrchestrationMode "flexible" `
-Location $location `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-PublicIpAddressName "myPublicIPAddress" `
-LoadBalancerName "myLoadBalancer" `
-Credential $cred
Enable encryption
To encrypt VM instances in a scale set, first get some information on the Key Vault URI and resource ID with Get-AzKeyVault. These variables are used to then start the encryption process with Set-AzVmssDiskEncryptionExtension:
$diskEncryptionKeyVaultUrl=(Get-AzKeyVault -ResourceGroupName $rgName -Name $vaultName).VaultUri
$keyVaultResourceId=(Get-AzKeyVault -ResourceGroupName $rgName -Name $vaultName).ResourceId
Set-AzVmssDiskEncryptionExtension -ResourceGroupName $rgName -VMScaleSetName $vmssName `
-DiskEncryptionKeyVaultUrl $diskEncryptionKeyVaultUrl -DiskEncryptionKeyVaultId $keyVaultResourceId -VolumeType "All"
When prompted, type y to continue the disk encryption process on the scale set VM instances.
Enable encryption using KEK to wrap the key
You can also use a Key Encryption Key for added security when encrypting the Virtual Machine Scale Set.
$diskEncryptionKeyVaultUrl=(Get-AzKeyVault -ResourceGroupName $rgName -Name $vaultName).VaultUri
$keyVaultResourceId=(Get-AzKeyVault -ResourceGroupName $rgName -Name $vaultName).ResourceId
$keyEncryptionKeyUrl = (Get-AzKeyVaultKey -VaultName $vaultName -Name $keyEncryptionKeyName).Key.kid;
Set-AzVmssDiskEncryptionExtension -ResourceGroupName $rgName -VMScaleSetName $vmssName `
-DiskEncryptionKeyVaultUrl $diskEncryptionKeyVaultUrl -DiskEncryptionKeyVaultId $keyVaultResourceId `
-KeyEncryptionKeyUrl $keyEncryptionKeyUrl -KeyEncryptionKeyVaultId $keyVaultResourceId -VolumeType "All"
Note
The syntax for the value of disk-encryption-keyvault parameter is the full identifier string:
/subscriptions/[subscription-id-guid]/resourceGroups/[resource-group-name]/providers/Microsoft.KeyVault/vaults/[keyvault-name]
The syntax for the value of the key-encryption-key parameter is the full URI to the KEK as in:
https://[keyvault-name].vault.azure.net/keys/[kekname]/[kek-unique-id]
Check encryption progress
To check on the status of disk encryption, use Get-AzVmssDiskEncryption:
Get-AzVmssDiskEncryption -ResourceGroupName $rgName -VMScaleSetName $vmssName
When VM instances are encrypted, the EncryptionSummary code reports ProvisioningState/succeeded as shown in the following example output:
ResourceGroupName : myResourceGroup
VmScaleSetName : myScaleSet
EncryptionSettings :
KeyVaultURL : https://myuniquekeyvault.vault.azure.net/
KeyEncryptionKeyURL :
KeyVaultResourceId : /subscriptions/guid/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myuniquekeyvault
KekVaultResourceId :
KeyEncryptionAlgorithm :
VolumeType : All
EncryptionOperation : EnableEncryption
EncryptionSummary[0] :
Code : ProvisioningState/succeeded
Count : 2
EncryptionEnabled : True
EncryptionExtensionInstalled : True
Disable encryption
If you no longer wish to use encrypted VM instances disks, you can disable encryption with Disable-AzVmssDiskEncryption as follows:
Disable-AzVmssDiskEncryption -ResourceGroupName $rgName -VMScaleSetName $vmssName
Next steps
- In this article, you used Azure PowerShell to encrypt a Virtual Machine Scale Set. You can also use the Azure CLI or Azure Resource Manager templates.
- If you wish to have Azure Disk Encryption applied after another extension is provisioned, you can use extension sequencing.