Azure Policy “Encryption at Host”

In this blog we can see the steps to enable the Encryption at host for VMs and AKS nodes.

The policy targets the resource types Microsoft.Compute/virtualMachines and Microsoft.Compute/virtualMachineScaleSets, with the field securityProfile.encryptionAtHost

For New VM

Check the status of the Azure Feature

Azure CLIaz loginaz feature show --namespace "Microsoft.Compute" --name "EncryptionAtHost" --query "properties.state"
Azure PowerShellConnect-AzAccountGet-AzProviderFeature -FeatureName "EncryptionAtHost" -ProviderNamespace "Microsoft.Compute"

Register the Azure Feature

Azure CLIaz loginaz feature register --namespace "Microsoft.Compute" --name "EncryptionAtHost"
Azure PowerShellConnect-AzAccountRegister-AzProviderFeature -FeatureName "EncryptionAtHost" -ProviderNamespace "Microsoft.Compute"

az account set --subscription "<your-subscription-id>"

Deploying VM using AZ CLI command

  • Without “–encryption-at-host” parameter – Disallowed by our Policy
    • “–encryption-at-host” parameter value set to false – Disallowed by our Policy
      • “–encryption-at-host” parameter value set to true- VM deployed successfully

Sample:

az vm create `
--name <your-vm-name>`
--resource-group <your-resource-group-name>`
--image "<your-image-name>" `
--size <your-sku-name> `
--admin-username <your-username> `
--admin-password <your-password> `
--authentication-type password `
--security-type TrustedLaunch `
--enable-vtpm true `
--enable-secure-boot true `
--encryption-at-host true `
--vnet-name <your-vnet-name>`
--subnet <your-subnet-name> `
--nics-delete-option delete `
--os-disk-delete-option delete `
--public-ip-address "" `
--no-wait

Deploying VM using AZ PowerShell command

Without “-EncryptionAtHost” parameter – Disallowed by our Policy

With “-EncryptionAtHost” parameter – VM deployed successfully

For Existing VMs

It cannot be enabled if Azure Disk Encryption (ADE) is already enabled

<PowerShell>

$rg_name = "<your-resource-group>"

$vm_name = "<your-vm-name>

# Deallocate VM

Stop-AzVM -ResourceGroupName $rg_name -Name $vm_name -Force

# Enable Encryption at Host
$vm = Get-AzVM -ResourceGroupName $rg_name -Name $vm_name
$vm.SecurityProfile = @{EncryptionAtHost = $true}
Update-AzVM -ResourceGroupName $rg_name -VM $vm

AKS Nodes

Encryption at Host

  • This encrypts data before it is written to disk, at the hypervisor level, offering a higher level of protection.
  • It must be explicitly enabled during node pool creation using Azure CLI or Terraform.
  • This setting is not visible in the Azure Portal, which is why the portal still shows “Not enabled” even if it was configured.

To verify if encryption at host is enabled, please run the following Azure CLI command:

az aks show \

  –resource-group Ganeshtest \

  –name test-encrypt-aks \

  –query “agentPoolProfiles[].enableEncryptionAtHost”

If the output is true, Then encryption at host is confirmed as enabled on your node pool.

Encryption at host cannot be enabled in AKS Cluster using Azure Portal. It can be done only via Azure CLI and Terraform
command:

az aks create \

  –name test-encrypt-aks \

  –resource-group Ganeshtest \

  –node-vm-size Standard_D4ds_v5 \

  –enable-encryption-at-host \

  –node-count 1 \

  –generate-ssh-keys

After performing the above command successfully, Add a user node pool with encryption at host:

Existing Node Pools cannot be modified to enable encryption at host. Those node Pools must be deleted and new ones should be created with encryption enabled. Using this command:

az aks nodepool add \

  –resource-group Ganeshtest \

  –cluster-name test-encrypt-aks \

  –name userpool1 \

  –node-vm-size Standard_D4ds_v5 \

  –node-count 1 \

  –mode User \

  –enable-encryption-at-host

AKS cluster must have at least one node pool designated as a “System” node pool to ensure that essential system services continue to run. 

In AKS, at least one node pool must be marked as a system mode pool, which is responsible for hosting critical system components like CoreDNS, kube-proxy, and Azure Policy pods. Since the original agentpool is still the only system node pool in the cluster

To resolve this, you’ll need to create a new node pool with –mode System specified in the command. Once that new system node pool is up and running,

az aks nodepool add –name newagpool –cluster-name ganeshtesttobedel-ci-aks–resource-group Ganeshtest –node-vm-size Standard_D4ds_v5 –enable-encryption-at-host –mode System 

These are the steps to migrate the pods to a healthy node pool:


1. Cordon the failing node pool
This marks its nodes as unschedulable.

kubectl get nodes -l agentpool=<oldpool-name> # repeat for each node kubectl cordon <node-name>

2. Evict running pods from failing nodes
This safely drains pods from the failing nodes to the healthy ones.

kubectl drain <node-name> –ignore-daemonsets –delete-emptydir-data

Repeat for each node in the failed pool.
Pods are automatically rescheduled 

3. Delete the failed node pool

Deploying VMs with Terraform

If you are deploying VMs with Terraform you should have the following line:

encryption_at_host_enabled = true

This entry was posted in Azure, Azure policy, Cloud and tagged , , , , , . Bookmark the permalink.

Leave a comment