Skip to content

Fix VMSizes-Must-Match-Template to support nested output properties#799

Draft
Copilot wants to merge 5 commits intomasterfrom
copilot/fix-vm-size-selector-nested-outputs
Draft

Fix VMSizes-Must-Match-Template to support nested output properties#799
Copilot wants to merge 5 commits intomasterfrom
copilot/fix-vm-size-selector-nested-outputs

Conversation

Copy link
Contributor

Copilot AI commented Feb 13, 2026

The VMSizes-Must-Match-Template test only checked first-level output properties, causing false negatives when VM SizeSelector references were nested 2+ levels deep.

Problem

When outputs were structured with nested objects:

"outputs": {
  "clusters": {
    "slurm": {
      "schedulerNode": {
        "sku": "[steps('scheduler').schedulerSection.vmsize]"
      }
    }
  }
}

The test would fail with "Could not find VM SizeSelector 'vmsize' in outputs" because it only iterated top-level properties where $out.Value is an object, not a string.

Changes

  • Added Find-OutputProperty helper function: Recursively traverses nested objects to locate VM SizeSelector patterns at any depth while preserving the top-level property name for template parameter matching
  • Updated search logic: Replaced flat property iteration with recursive search call
  • Added test coverage: 2-level, 3-level, and multi-selector nested output scenarios

The recursive function checks if a value is a string matching the pattern, or an object requiring further traversal. It returns the top-level property name (e.g., "clusters") needed for $MainTemplateParameters lookup, not the full nested path.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • aka.ms
    • Triggering command: /usr/bin/pwsh pwsh -Command Import-Module ./arm-ttk/arm-ttk.psd1 -Force; Test-AzTemplate -TemplatePath './unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels' -Test 'VMSizes-Must-Match-Template' (dns block)
    • Triggering command: /usr/bin/pwsh pwsh -Command Import-Module ./arm-ttk/arm-ttk.psd1 -Force; Test-AzTemplate -TemplatePath './unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels' -Test 'VMSizes-Must-Match-Template' (dns block)
    • Triggering command: /usr/bin/pwsh pwsh -Command Import-Module ./arm-ttk/arm-ttk.psd1 -Force; Test-AzTemplate -TemplatePath './unit-tests/VMSizes-Must-Match-Template/Pass/Element-Nested-In-Section' -Test 'VMSizes-Must-Match-Template' (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Can't use VM SizeSelector in nested outputs</issue_title>
<issue_description>Hello,

I have the following output object in my uidefinition.json file:

"clusters": {
        "slurm": {
          "startCluster": "[steps('scheduler').clusterSettings.startCluster]",
          "version": "[steps('scheduler').schedulerSection.slurmVersion]",
          "healthCheckEnabled": "[steps('scheduler').clusterSettings.healthCheck]",
          "schedulerNode": {
            "sku": "[steps('scheduler').schedulerSection.vmsize]",
            "osImage": "[if(equals(steps('scheduler').schedulerSection.ImageName,'custom'),steps('scheduler').schedulerSection.customImageName,steps('scheduler').schedulerSection.ImageName)]"
          },
          "loginNodes": {
            "sku": "[steps('scheduler').loginNodesSection.vmsize]",
            "osImage": "[if(not(steps('scheduler').schedulerSection.universalImage),if(equals(steps('scheduler').loginNodesSection.ImageName,'custom'),steps('scheduler').loginNodesSection.customImageName,steps('scheduler').loginNodesSection.ImageName),if(equals(steps('scheduler').schedulerSection.ImageName,'custom'),steps('scheduler').schedulerSection.customImageName,steps('scheduler').schedulerSection.ImageName))]",
            "initialNodes": "[int(steps('scheduler').loginNodesSection.initialNodes)]",
            "maxNodes": "[int(steps('scheduler').loginNodesSection.maxNodes)]"
          },
          "htc": {
            "sku": "[steps('slurmSettings').HTCSection.vmsize]",
            "maxNodes": "[int(steps('slurmSettings').HTCSection.maxNodes)]",
            "osImage": "[if(not(steps('scheduler').schedulerSection.universalImage),if(equals(steps('slurmSettings').HTCSection.ImageName,'custom'),steps('slurmSettings').HTCSection.customImageName,steps('slurmSettings').HTCSection.ImageName),if(equals(steps('scheduler').schedulerSection.ImageName,'custom'),steps('scheduler').schedulerSection.customImageName,steps('scheduler').schedulerSection.ImageName))]",
            "useSpot": "[steps('slurmSettings').HTCSection.spotHTC]"
          },
          "hpc": {
            "sku": "[steps('slurmSettings').HPCSection.vmsize]",
            "maxNodes": "[int(steps('slurmSettings').HPCSection.maxNodes)]",
            "osImage": "[if(not(steps('scheduler').schedulerSection.universalImage),if(equals(steps('slurmSettings').HPCSection.ImageName,'custom'),steps('slurmSettings').HPCSection.customImageName,steps('slurmSettings').HPCSection.ImageName),if(equals(steps('scheduler').schedulerSection.ImageName,'custom'),steps('scheduler').schedulerSection.customImageName,steps('scheduler').schedulerSection.ImageName))]"
          },
          "gpu": {
            "sku": "[steps('slurmSettings').GPUSection.vmsize]",
            "maxNodes": "[int(steps('slurmSettings').GPUSection.maxNodes)]",
            "osImage": "[if(not(steps('scheduler').schedulerSection.universalImage),if(equals(steps('slurmSettings').GPUSection.ImageName,'custom'),steps('slurmSettings').GPUSection.customImageName,steps('slurmSettings').GPUSection.ImageName),if(equals(steps('scheduler').schedulerSection.ImageName,'custom'),steps('scheduler').schedulerSection.customImageName,steps('scheduler').schedulerSection.ImageName))]"
          }
        },
        "ood": {
          "type": "[if(steps('ood').OODSection.deployOOD,'enabled','disabled')]",
          "startCluster": "[if(steps('ood').OODSection.deployOOD,steps('ood').OODSection.startCluster,basics('nullValue'))]",
          "sku": "[if(steps('ood').OODSection.deployOOD,steps('ood').OODSection.vmsize,basics('nullValue'))]",
          "osImage": "[if(steps('ood').OODSection.deployOOD,if(equals(steps('ood').OODSection.ImageName,'custom'),steps('ood').OODSection.customImageName,steps('ood').OODSection.ImageName),basics('nullValue'))]",
          "userDomain": "[if(steps('ood').OODSection.deployOOD,steps('ood').OODSection.userDomain,basics('nullValue'))]",
          "fqdn": "[if(not(equals(steps('ood').OODSection.fqdn,'')),steps('ood').OODSection.fqdn,basics('nullValue'))]",
          "registerEntraIDApp": "[if(steps('ood').OODSection.deployOOD,equals(steps('ood').OODSection.registerEntraIDApp,'autoregister'),basics('nullValue'))]",
          "appId": "[if(equals(steps('ood').OODSection.registerEntraIDApp,'existing'),steps('ood').OODSection.clientId,basics('nullValue'))]",
          "appManagedIdentityId": "[if(equals(steps('ood').OODSection.registerEntraIDApp,'existing'),steps('ood').OODSection.managedIdentity.id,basics('nullValue'))]"
        }
      }

This fails validation because ARM-ttk doesn't recognize that the VM SizeSelector elements are present in the outputs when they're multiple levels deep into an object. Here's the result from using the above in a UI definition JSON:

Image

Validation passes, however, when one level ...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits February 13, 2026 22:08
Co-authored-by: psah434 <114955590+psah434@users.noreply.github.com>
Co-authored-by: psah434 <114955590+psah434@users.noreply.github.com>
…and parameter naming

Co-authored-by: psah434 <114955590+psah434@users.noreply.github.com>
Co-authored-by: psah434 <114955590+psah434@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix VM SizeSelector issue in nested outputs Fix VMSizes-Must-Match-Template to support nested output properties Feb 13, 2026
Copilot AI requested a review from psah434 February 13, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't use VM SizeSelector in nested outputs

2 participants