Skip to content

trustedLaunch overwrites securityProfile, dropping encryptionAtHost #783

Description

@NoamGoren

Summary

When trustedLaunch: true and encryptionAtHost: true are both set on a VM template, the plugin drops encryptionAtHost from the ARM deployment template. Azure policy then blocks VM creation because encryption at host is missing.

Root Cause

In AzureVMManagementServiceDelegate.java, the addTrustedLaunch() method replaces the entire securityProfile property on the VM resource instead of merging with it.

The ARM templates (e.g. referenceImageIDTemplateWithManagedDisk.json) correctly set:

"securityProfile": {
  "encryptionAtHost": "[if(bool(variables('encryptionAtHost')), json('true'), json('null'))]"
}

But addTrustedLaunch() overwrites this with:

properties.put("securityProfile",
    "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]");

Where securityProfileJson only contains uefiSettings + securityType — no encryptionAtHost:

ObjectNode profileNode = MAPPER.createObjectNode();
ObjectNode settingsNode = MAPPER.createObjectNode();
settingsNode.put("secureBootEnabled", true);
settingsNode.put("vTpmEnabled", true);
profileNode.set("uefiSettings", settingsNode);
profileNode.put("securityType", "[parameters('securityType')]");
variableNode.set("securityProfileJson", profileNode);

Steps to Reproduce

  1. Configure an Azure VM agent template with:
    • trustedLaunch: true
    • encryptionAtHost: true
    • A gallery image that requires TrustedLaunch security type
  2. Trigger agent provisioning
  3. Deployment fails with RequestDisallowedByPolicy — Azure policy requires encryption at host, but the deployed ARM template has no encryptionAtHost in the securityProfile

Error

com.azure.core.management.exception.ManagementException: Status code 400,
"error": {
  "code": "InvalidTemplateDeployment",
  "details": [{
    "code": "RequestDisallowedByPolicy",
    "message": "Resource 'azure-vmXXXXXX' was disallowed by policy.
      Reasons: 'Virtual machines must have encryption at host enabled to protect data at rest.'"
  }]
}

Setting trustedLaunch: false is not a workaround because the gallery image itself requires TrustedLaunch, producing:

AzureCloudException: Deployment Failed: Microsoft.Compute/virtualMachines:azure-vmXXXXXX
  - BadRequest - The provided gallery image only supports creation of VMs and VM Scale Sets
    with 'TrustedLaunch' security type.

Suggested Fix

Include encryptionAtHost in the securityProfileJson variable built by addTrustedLaunch():

profileNode.set("uefiSettings", settingsNode);
profileNode.put("securityType", "[parameters('securityType')]");
profileNode.put("encryptionAtHost", "[bool(variables('encryptionAtHost'))]");  // preserve encryptionAtHost
variableNode.set("securityProfileJson", profileNode);

This ensures the TrustedLaunch security profile merges with (rather than replaces) the encryption-at-host setting.

Environment

  • Plugin version: 1103.ve4a_50ca_2c617 (also checked 1105 — same code path)
  • Jenkins: CloudBees CI (managed controller)
  • Azure region: West US 2
  • OS: Windows 11 25H2 (gallery image with TrustedLaunch security type)

Impact

This is a blocking issue for any environment where Azure policy enforces both TrustedLaunch on gallery images and encryption-at-host on VMs — there is no valid combination of plugin settings that passes both policies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions