Skip to content

{Compute} az vmss: Migrate command group to aaz-based implementation#32857

Open
william051200 wants to merge 23 commits intoAzure:devfrom
william051200:vmss-migration
Open

{Compute} az vmss: Migrate command group to aaz-based implementation#32857
william051200 wants to merge 23 commits intoAzure:devfrom
william051200:vmss-migration

Conversation

@william051200
Copy link
Member

Related command

az vmss create
az vmss show
az vmss update
az vmss wait

Description

Migration from mgmt.compute to aaz-based

Testing Guide

History Notes


This checklist is used to make sure that common guidelines for a pull request are followed.

Copilot AI review requested due to automatic review settings February 26, 2026 00:02
@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Feb 26, 2026

❌AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.13
️✔️acs
️✔️latest
️✔️3.12
️✔️3.13
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.13
️✔️ams
️✔️latest
️✔️3.12
️✔️3.13
️✔️apim
️✔️latest
️✔️3.12
️✔️3.13
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.13
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️aro
️✔️latest
️✔️3.12
️✔️3.13
️✔️backup
️✔️latest
️✔️3.12
️✔️3.13
️✔️batch
️✔️latest
️✔️3.12
️✔️3.13
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.13
️✔️billing
️✔️latest
️✔️3.12
️✔️3.13
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.13
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.13
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.13
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.13
️✔️config
️✔️latest
️✔️3.12
️✔️3.13
️✔️configure
️✔️latest
️✔️3.12
️✔️3.13
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.13
️✔️container
️✔️latest
️✔️3.12
️✔️3.13
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.13
️✔️core
️✔️latest
️✔️3.12
️✔️3.13
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.13
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.13
️✔️dls
️✔️latest
️✔️3.12
️✔️3.13
️✔️dms
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.13
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.13
️✔️find
️✔️latest
️✔️3.12
️✔️3.13
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.13
️✔️identity
️✔️latest
️✔️3.12
️✔️3.13
️✔️iot
️✔️latest
️✔️3.12
️✔️3.13
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.13
️✔️lab
️✔️latest
️✔️3.12
️✔️3.13
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️maps
️✔️latest
️✔️3.12
️✔️3.13
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.13
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.13
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.13
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.13
️✔️network
️✔️latest
️✔️3.12
️✔️3.13
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.13
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.13
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.13
️✔️profile
️✔️latest
️✔️3.12
️✔️3.13
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.13
️✔️redis
️✔️latest
️✔️3.12
️✔️3.13
️✔️relay
️✔️latest
️✔️3.12
️✔️3.13
️✔️resource
️✔️latest
️✔️3.12
️✔️3.13
️✔️role
️✔️latest
️✔️3.12
️✔️3.13
️✔️search
️✔️latest
️✔️3.12
️✔️3.13
️✔️security
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.13
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.13
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.13
️✔️sql
️✔️latest
️✔️3.12
️✔️3.13
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.13
️✔️storage
️✔️latest
️✔️3.12
️✔️3.13
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.13
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.13
️✔️util
️✔️latest
️✔️3.12
️✔️3.13
❌vm
❌latest
❌3.12
Type Test Case Error Message Line
Failed test_vm_restore_point_instant_access self = <azure.cli.core.commands.AzCliCommandInvoker object at 0x7f36ec589df0>
parsed_ns = Namespace(log_verbosity_verbose=False, log_verbosity_debug=False, log_verbosity_only_show_errors=False, output_for...ngeTag object at 0x7f36eb9bda60>, <azure.cli.core.breaking_change.UpcomingBreakingChangeTag object at 0x7f36eb9bda60>])

    def validation(self, parsed_ns):
        try:
            cmd_validator = getattr(parsed_ns, 'command_validator', None)
            if cmd_validator:
>               self.validate_cmd_level(parsed_ns, cmd_validator)

env/lib/python3.12/site-packages/knack/invocation.py:111: 
 
 
 
 
 
 
                                  
src/azure-cli-core/azure/cli/core/commands/init.py:989: in validate_cmd_level
    cmd_validator(**self.build_kwargs(cmd_validator, ns))
src/azure-cli/azure/cli/command_modules/vm/validators.py:1609: in process_vm_create_namespace
    validate_vm_vmss_create_public_ip(cmd, namespace)
src/azure-cli/azure/cli/command_modules/vm/validators.py:1065: in validate_vm_vmss_create_public_ip
    if check_existence(cmd.cli_ctx, namespace.public_ip_address, namespace.resource_group_name,
src/azure-cli/azure/cli/command_modules/vm/vm_utils.py:102: in check_existence
    resource_client.get(rg, ns, parent_path, resource_type, resource_name, api_version)
env/lib/python3.12/site-packages/azure/core/tracing/decorator.py:119: in wrapper_use_tracer
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/mgmt/resource/resources/v2024_11_01/operations/operations.py:5145: in get
    pipeline_response: PipelineResponse = self.client.pipeline.run(  # pylint: disable=protected-access
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:242: in run
    return first_node.send(pipeline_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/mgmt/core/policies/base.py:95: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/policies/redirect.py:205: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/policies/retry.py:545: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/policies/authentication.py:161: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/base.py:130: in send
    self.sender.send(request.http_request, **request.context.options),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/azure/core/pipeline/transport/requests_basic.py:375: in send
    response = self.session.request(  # type: ignore
env/lib/python3.12/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/requests/adapters.py:667: in send
    resp = conn.urlopen(
env/lib/python3.12/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self.make_request(
env/lib/python3.12/site-packages/urllib3/connectionpool.py:534: in make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
          

self = <VCRRequestsHTTPSConnection/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vm_restore_point_instant_access.yaml(host='management.azure.com', port=443) at 0x7f36eb5e56d0>
 = False, kwargs = {}

    def getresponse(self, 
=False, **kwargs):
        """Retrieve the response"""
        # Check to see if the cassette has a response for this request. If so,
        # then return it
        if self.cassette.can_play_response_for(self.vcr_request):
            log.info(f"Playing response for {self.vcr_request} from cassette")
            response = self.cassette.play_response(self.vcr_request)
            return VCRHTTPResponse(response)
        else:
            if self.cassette.write_protected and self.cassette.filter_request(self.vcr_request):
>               raise CannotOverwriteExistingCassetteException(
                    cassette=self.cassette,
                    failed_request=self.vcr_request,
                )
E               vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vm_restore_point_instant_access.yaml') in your current record mode ('once').
E               No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_vm_rp_ia000001/providers/Microsoft.Network//publicIPAddresses/testPip1?api-version=2022-05-01>)&nbsp;was&nbsp;found.
E               Found 1 similar requests with 1 different matcher(s) :
E               
E               1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_vm_rp_ia000001/providers/Microsoft.Network/publicIPAddresses/testPip1?api-version=2025-07-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path']
E               Matchers failed :
E               custom_request_query_matcher - assertion failure :
E               None

env/lib/python3.12/site-packages/vcr/stubs/init.py:277: CannotOverwriteExistingCassetteException

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.VMRestorePointInstantAccessScenarioTest testMethod=test_vm_restore_point_instant_access>
resource_group = 'cli_test_vm_rp_ia000001'

    @ResourceGroupPreparer(name_prefix='cli_test_vm_rp_ia', location='eastus2euap')
    @AllowLargeResponse(size_kb=99999)
    def test_vm_restore_point_instant_access(self, resource_group):
        self.kwargs.update({
            'vm': 'testVm1',
            'vnet': 'testVnet1',
            'subnet': 'testSubnet1',
            'pip': 'testPip1',
            'disk': 'testDdv2',
            'rpc': 'testRpc1',
            'rp': 'testRp1',
            'location': 'eastus2euap'
        })
    
        # Create VM
>       vm = self.cmd('vm create -g {rg} -n {vm} --image Win2022Datacenter --admin-username azureuser --admin-password '
                      '"Password12345!" --size Standard_D2s_v3 --vnet-name {vnet} -l {location} '
                      '--subnet {subnet} --public-ip-address {pip} --zone 1').get_output_in_json()

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13988: 
 
 
 
 
 
 
                                  
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: in in_process_execute
    self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.12/site-packages/knack/cli.py:250: in invoke
    raise ex
env/lib/python3.12/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:666: in execute
    self.validation(expanded_arg)
env/lib/python3.12/site-packages/knack/invocation.py:118: in validation
    getattr(parsed_ns, 'parser', self.parser).validation_error(str(err))
src/azure-cli-core/azure/cli/core/parser.py:150: in validation_error
    self.exit(2)
 
 
 
 
 
                                   

self = AzCliCommandParser(prog='az vm create', usage=None, description='', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
status = 2, message = None

    def exit(self, status=0, message=None):
        if message:
            self._print_message(message, _sys.stderr)
>       _sys.exit(status)
E       SystemExit: 2

/opt/hostedtoolcache/Python/3.12.12/x64/lib/python3.12/argparse.py:2637: SystemExit
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13972
Failed test_vmss_update_max_instance_percent_per_zone self = <latest.test_vm_commands.VMSSUpdateZoneAllocationPolicyTest testMethod=test_vmss_update_max_instance_percent_per_zone>
resource_group = 'cli_test_vmss_update_instance_percent_000001'

    @ResourceGroupPreparer(name_prefix='cli_test_vmss_update_instance_percent_')
    def test_vmss_update_max_instance_percent_per_zone(self, resource_group):
        self.kwargs.update({
            'vmss': 'vmss-update-instance-percent',
            'location': 'eastus2euap',
            'image': 'OpenLogic:CentOS:7.5:latest',
            'admin_username': 'testadmin',
            'admin_password': 'testPassword0!@#',
            'vm_sku': 'Standard_B2ms'
        })
    
        # create vmss without instance percent policy
        self.cmd(
            'vmss create -g {rg} -n {vmss} -l {location} '
            '--image {image} '
            '--admin-username {admin_username} '
            '--admin-password {admin_password} '
            '--upgrade-policy-mode Manual '
            '--zone-placement-policy Auto '
            '--vm-sku {vm_sku} '
        )
    
        # update vmss with instance percent policy
        self.cmd(
            'vmss update -g {rg} -n {vmss} '
            '--instance-percent-policy true '
            '--max-instance-percent 80'
        )
    
        # verify the policy was enabled with correct value
        self.cmd('vmss show -g {rg} -n {vmss}', checks=[
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled', True),
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.value', 80)
        ])
    
        # update the percent value
        self.cmd(
            'vmss update -g {rg} -n {vmss} '
            '--instance-percent-policy true '
            '--max-instance-percent 90'
        )
    
        # verify the value was updated
>       self.cmd('vmss show -g {rg} -n {vmss}', checks=[
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled', True),
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.value', 90)
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:14384: 
                                        
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:278: in assert_with_checks
    c(self)
                                        

self = <azure.cli.testsdk.checkers.JMESPathCheck object at 0x7f36eb2d0080>
execution_result = <azure.cli.testsdk.base.ExecutionResult object at 0x7f36eb2d0500>

    def call(self, execution_result):
        json_value = execution_result.get_output_in_json()
        actual_result = None
        try:
            actual_result = jmespath.search(self._query, json_value,
                                            jmespath.Options(collections.OrderedDict))
        except jmespath.exceptions.JMESPathTypeError:
            raise JMESPathCheckAssertionError(self._query, self._expected_result, actual_result,
                                              execution_result.output)
        if self._case_sensitive:
            equals = actual_result == self._expected_result or str(actual_result) == str(self._expected_result)
        else:
            equals = actual_result == self._expected_result <br>                or str(actual_result).lower() == str(self._expected_result).lower()
        if not equals:
            if actual_result:
                raise JMESPathCheckAssertionError(self._query, self._expected_result, actual_result,
                                                  execution_result.output)
>           raise JMESPathCheckAssertionError(self._query, self._expected_result, 'None',
                                              execution_result.output)
E           azure.cli.testsdk.exceptions.JMESPathCheckAssertionError: Query 'resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled' doesn't yield expected value 'True', instead the actual value is 'None'. Data: 
E           {
E             "constrainedMaximumCapacity": false,
E             "etag": ""4"",
E             "highSpeedInterconnectPlacement": "None",
E             "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Compute/virtualMachineScaleSets/vmss-update-instance-percent",
E             "location": "eastus2euap",
E             "name": "vmss-update-instance-percent",
E             "orchestrationMode": "Flexible",
E             "placement": {
E               "zonePlacementPolicy": "Auto"
E             },
E             "platformFaultDomainCount": 1,
E             "provisioningState": "Succeeded",
E             "resiliencyPolicy": {
E               "zoneAllocationPolicy": {
E                 "maxInstancePercentPerZonePolicy": {
E                   "enabled": false,
E                   "value": 90
E                 }
E               }
E             },
E             "resourceGroup": "cli_test_vmss_update_instance_percent_000001",
E             "singlePlacementGroup": false,
E             "sku": {
E               "capacity": 2,
E               "name": "Standard_B2ms",
E               "tier": "Standard"
E             },
E             "tags": {},
E             "timeCreated": "2026-02-23T04:44:10.3553116+00:00",
E             "type": "Microsoft.Compute/virtualMachineScaleSets",
E             "uniqueId": "3ecc08af-9d6f-470a-9ec5-db5a21c3bfa7",
E             "upgradePolicy": {
E               "mode": "Manual"
E             },
E             "virtualMachineProfile": {
E               "networkProfile": {
E                 "networkApiVersion": "2020-11-01",
E                 "networkInterfaceConfigurations": [
E                   {
E                     "auxiliaryMode": "None",
E                     "auxiliarySku": "None",
E                     "deleteOption": "Delete",
E                     "disableTcpStateTracking": false,
E                     "dnsSettings": {
E                       "dnsServers": []
E                     },
E                     "enableIPForwarding": false,
E                     "ipConfigurations": [
E                       {
E                         "applicationGatewayBackendAddressPools": [],
E                         "applicationSecurityGroups": [],
E                         "loadBalancerBackendAddressPools": [
E                           {
E                             "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/loadBalancers/vmss-update-instance-percentLB/backendAddressPools/vmss-update-instance-percentLBBEPool",
E                             "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                           }
E                         ],
E                         "name": "vmssueaa0IPConfig",
E                         "privateIPAddressVersion": "IPv4",
E                         "subnet": {
E                           "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/virtualNetworks/vmss-update-instance-percentVNET/subnets/vmss-update-instance-percentSubnet",
E                           "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                         }
E                       }
E                     ],
E                     "name": "vmssueaa0Nic",
E                     "networkSecurityGroup": {
E                       "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/networkSecurityGroups/vmss-update-instance-percentNSG",
E                       "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                     },
E                     "primary": true
E                   }
E                 ]
E               },
E               "osProfile": {
E                 "adminUsername": "testadmin",
E                 "allowExtensionOperations": true,
E                 "computerNamePrefix": "vmss-upd",
E                 "linuxConfiguration": {
E                   "disablePasswordAuthentication": false,
E                   "enableVMAgentPlatformUpdates": true,
E                   "patchSettings": {
E                     "assessmentMode": "ImageDefault",
E                     "patchMode": "ImageDefault"
E                   },
E                   "provisionVMAgent": true
E                 },
E                 "requireGuestProvisionSignal": true,
E                 "secrets": []
E               },
E               "storageProfile": {
E                 "imageReference": {
E                   "offer": "CentOS",
E                   "publisher": "OpenLogic",
E                   "sku": "7.5",
E                   "version": "latest"
E                 },
E                 "osDisk": {
E                   "caching": "ReadWrite",
E                   "createOption": "FromImage",
E                   "deleteOption": "Delete",
E                   "diskSizeGB": 30,
E                   "managedDisk": {
E                     "storageAccountType": "Premium_LRS"
E                   },
E                   "osType": "Linux"
E                 }
E               },
E               "timeCreated": "2026-02-23T04:46:12.1860441+00:00"
E             },
E             "zoneBalance": false
E           }

src/azure-cli-testsdk/azure/cli/testsdk/checkers.py:36: JMESPathCheckAssertionError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:14340
❌3.13
Type Test Case Error Message Line
Failed test_vm_restore_point_instant_access self = <azure.cli.core.commands.AzCliCommandInvoker object at 0x7f56312438c0>
parsed_ns = Namespace(log_verbosity_verbose=False, log_verbosity_debug=False, log_verbosity_only_show_errors=False, output_for...ngeTag object at 0x7f563091da90>, <azure.cli.core.breaking_change.UpcomingBreakingChangeTag object at 0x7f563091da90>])

    def validation(self, parsed_ns):
        try:
            cmd_validator = getattr(parsed_ns, 'command_validator', None)
            if cmd_validator:
>               self.validate_cmd_level(parsed_ns, cmd_validator)

env/lib/python3.13/site-packages/knack/invocation.py:111: 
 
 
 
 
 
 
                                  
src/azure-cli-core/azure/cli/core/commands/init.py:989: in validate_cmd_level
    cmd_validator(**self.build_kwargs(cmd_validator, ns))
src/azure-cli/azure/cli/command_modules/vm/validators.py:1609: in process_vm_create_namespace
    validate_vm_vmss_create_public_ip(cmd, namespace)
src/azure-cli/azure/cli/command_modules/vm/validators.py:1065: in validate_vm_vmss_create_public_ip
    if check_existence(cmd.cli_ctx, namespace.public_ip_address, namespace.resource_group_name,
src/azure-cli/azure/cli/command_modules/vm/vm_utils.py:102: in check_existence
    resource_client.get(rg, ns, parent_path, resource_type, resource_name, api_version)
env/lib/python3.13/site-packages/azure/core/tracing/decorator.py:119: in wrapper_use_tracer
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/mgmt/resource/resources/v2024_11_01/operations/operations.py:5145: in get
    pipeline_response: PipelineResponse = self.client.pipeline.run(  # pylint: disable=protected-access
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:242: in run
    return first_node.send(pipeline_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/mgmt/core/policies/base.py:95: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/policies/redirect.py:205: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/policies/retry.py:545: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/policies/authentication.py:161: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:98: in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/base.py:130: in send
    self.sender.send(request.http_request, **request.context.options),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/azure/core/pipeline/transport/requests_basic.py:375: in send
    response = self.session.request(  # type: ignore
env/lib/python3.13/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/requests/adapters.py:667: in send
    resp = conn.urlopen(
env/lib/python3.13/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self.make_request(
env/lib/python3.13/site-packages/urllib3/connectionpool.py:534: in make_request
    response = conn.getresponse()
               ^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
          

self = <VCRRequestsHTTPSConnection/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vm_restore_point_instant_access.yaml(host='management.azure.com', port=443) at 0x7f563045b360>
 = False, kwargs = {}

    def getresponse(self, 
=False, **kwargs):
        """Retrieve the response"""
        # Check to see if the cassette has a response for this request. If so,
        # then return it
        if self.cassette.can_play_response_for(self.vcr_request):
            log.info(f"Playing response for {self.vcr_request} from cassette")
            response = self.cassette.play_response(self.vcr_request)
            return VCRHTTPResponse(response)
        else:
            if self.cassette.write_protected and self.cassette.filter_request(self.vcr_request):
>               raise CannotOverwriteExistingCassetteException(
                    cassette=self.cassette,
                    failed_request=self.vcr_request,
                )
E               vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ('/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vm_restore_point_instant_access.yaml') in your current record mode ('once').
E               No match for the request (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_vm_rp_ia000001/providers/Microsoft.Network//publicIPAddresses/testPip1?api-version=2022-05-01>)&nbsp;was&nbsp;found.
E               Found 1 similar requests with 1 different matcher(s) :
E               
E               1 - (<Request (GET) https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/cli_test_vm_rp_ia000001/providers/Microsoft.Network/publicIPAddresses/testPip1?api-version=2025-07-01>).
E               Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path']
E               Matchers failed :
E               custom_request_query_matcher - assertion failure :
E               None

env/lib/python3.13/site-packages/vcr/stubs/init.py:277: CannotOverwriteExistingCassetteException

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.VMRestorePointInstantAccessScenarioTest testMethod=test_vm_restore_point_instant_access>
resource_group = 'cli_test_vm_rp_ia000001'

    @ResourceGroupPreparer(name_prefix='cli_test_vm_rp_ia', location='eastus2euap')
    @AllowLargeResponse(size_kb=99999)
    def test_vm_restore_point_instant_access(self, resource_group):
        self.kwargs.update({
            'vm': 'testVm1',
            'vnet': 'testVnet1',
            'subnet': 'testSubnet1',
            'pip': 'testPip1',
            'disk': 'testDdv2',
            'rpc': 'testRpc1',
            'rp': 'testRp1',
            'location': 'eastus2euap'
        })
    
        # Create VM
>       vm = self.cmd('vm create -g {rg} -n {vm} --image Win2022Datacenter --admin-username azureuser --admin-password '
                      '"Password12345!" --size Standard_D2s_v3 --vnet-name {vnet} -l {location} '
                      '--subnet {subnet} --public-ip-address {pip} --zone 1').get_output_in_json()

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13988: 
 
 
 
 
 
 
                                  
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: in in_process_execute
    self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
env/lib/python3.13/site-packages/knack/cli.py:250: in invoke
    raise ex
env/lib/python3.13/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:666: in execute
    self.validation(expanded_arg)
env/lib/python3.13/site-packages/knack/invocation.py:118: in validation
    getattr(parsed_ns, 'parser', self.parser).validation_error(str(err))
src/azure-cli-core/azure/cli/core/parser.py:150: in validation_error
    self.exit(2)
 
 
 
 
 
                                   

self = AzCliCommandParser(prog='az vm create', usage=None, description='', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
status = 2, message = None

    def exit(self, status=0, message=None):
        if message:
            self._print_message(message, _sys.stderr)
>       _sys.exit(status)
E       SystemExit: 2

/opt/hostedtoolcache/Python/3.13.11/x64/lib/python3.13/argparse.py:2645: SystemExit
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13972
Failed test_vmss_update_max_instance_percent_per_zone self = <latest.test_vm_commands.VMSSUpdateZoneAllocationPolicyTest testMethod=test_vmss_update_max_instance_percent_per_zone>
resource_group = 'cli_test_vmss_update_instance_percent_000001'

    @ResourceGroupPreparer(name_prefix='cli_test_vmss_update_instance_percent_')
    def test_vmss_update_max_instance_percent_per_zone(self, resource_group):
        self.kwargs.update({
            'vmss': 'vmss-update-instance-percent',
            'location': 'eastus2euap',
            'image': 'OpenLogic:CentOS:7.5:latest',
            'admin_username': 'testadmin',
            'admin_password': 'testPassword0!@#',
            'vm_sku': 'Standard_B2ms'
        })
    
        # create vmss without instance percent policy
        self.cmd(
            'vmss create -g {rg} -n {vmss} -l {location} '
            '--image {image} '
            '--admin-username {admin_username} '
            '--admin-password {admin_password} '
            '--upgrade-policy-mode Manual '
            '--zone-placement-policy Auto '
            '--vm-sku {vm_sku} '
        )
    
        # update vmss with instance percent policy
        self.cmd(
            'vmss update -g {rg} -n {vmss} '
            '--instance-percent-policy true '
            '--max-instance-percent 80'
        )
    
        # verify the policy was enabled with correct value
        self.cmd('vmss show -g {rg} -n {vmss}', checks=[
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled', True),
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.value', 80)
        ])
    
        # update the percent value
        self.cmd(
            'vmss update -g {rg} -n {vmss} '
            '--instance-percent-policy true '
            '--max-instance-percent 90'
        )
    
        # verify the value was updated
>       self.cmd('vmss show -g {rg} -n {vmss}', checks=[
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled', True),
            self.check('resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.value', 90)
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:14384: 
                                        
src/azure-cli-testsdk/azure/cli/testsdk/base.py:177: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:278: in assert_with_checks
    c(self)
                                        

self = <azure.cli.testsdk.checkers.JMESPathCheck object at 0x7f56303e1950>
execution_result = <azure.cli.testsdk.base.ExecutionResult object at 0x7f5630347e10>

    def call(self, execution_result):
        json_value = execution_result.get_output_in_json()
        actual_result = None
        try:
            actual_result = jmespath.search(self._query, json_value,
                                            jmespath.Options(collections.OrderedDict))
        except jmespath.exceptions.JMESPathTypeError:
            raise JMESPathCheckAssertionError(self._query, self._expected_result, actual_result,
                                              execution_result.output)
        if self._case_sensitive:
            equals = actual_result == self._expected_result or str(actual_result) == str(self._expected_result)
        else:
            equals = actual_result == self._expected_result <br>                or str(actual_result).lower() == str(self._expected_result).lower()
        if not equals:
            if actual_result:
                raise JMESPathCheckAssertionError(self._query, self._expected_result, actual_result,
                                                  execution_result.output)
>           raise JMESPathCheckAssertionError(self._query, self._expected_result, 'None',
                                              execution_result.output)
E           azure.cli.testsdk.exceptions.JMESPathCheckAssertionError: Query 'resiliencyPolicy.zoneAllocationPolicy.maxInstancePercentPerZonePolicy.enabled' doesn't yield expected value 'True', instead the actual value is 'None'. Data: 
E           {
E             "constrainedMaximumCapacity": false,
E             "etag": ""4"",
E             "highSpeedInterconnectPlacement": "None",
E             "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Compute/virtualMachineScaleSets/vmss-update-instance-percent",
E             "location": "eastus2euap",
E             "name": "vmss-update-instance-percent",
E             "orchestrationMode": "Flexible",
E             "placement": {
E               "zonePlacementPolicy": "Auto"
E             },
E             "platformFaultDomainCount": 1,
E             "provisioningState": "Succeeded",
E             "resiliencyPolicy": {
E               "zoneAllocationPolicy": {
E                 "maxInstancePercentPerZonePolicy": {
E                   "enabled": false,
E                   "value": 90
E                 }
E               }
E             },
E             "resourceGroup": "cli_test_vmss_update_instance_percent_000001",
E             "singlePlacementGroup": false,
E             "sku": {
E               "capacity": 2,
E               "name": "Standard_B2ms",
E               "tier": "Standard"
E             },
E             "tags": {},
E             "timeCreated": "2026-02-23T04:44:10.3553116+00:00",
E             "type": "Microsoft.Compute/virtualMachineScaleSets",
E             "uniqueId": "3ecc08af-9d6f-470a-9ec5-db5a21c3bfa7",
E             "upgradePolicy": {
E               "mode": "Manual"
E             },
E             "virtualMachineProfile": {
E               "networkProfile": {
E                 "networkApiVersion": "2020-11-01",
E                 "networkInterfaceConfigurations": [
E                   {
E                     "auxiliaryMode": "None",
E                     "auxiliarySku": "None",
E                     "deleteOption": "Delete",
E                     "disableTcpStateTracking": false,
E                     "dnsSettings": {
E                       "dnsServers": []
E                     },
E                     "enableIPForwarding": false,
E                     "ipConfigurations": [
E                       {
E                         "applicationGatewayBackendAddressPools": [],
E                         "applicationSecurityGroups": [],
E                         "loadBalancerBackendAddressPools": [
E                           {
E                             "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/loadBalancers/vmss-update-instance-percentLB/backendAddressPools/vmss-update-instance-percentLBBEPool",
E                             "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                           }
E                         ],
E                         "name": "vmssueaa0IPConfig",
E                         "privateIPAddressVersion": "IPv4",
E                         "subnet": {
E                           "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/virtualNetworks/vmss-update-instance-percentVNET/subnets/vmss-update-instance-percentSubnet",
E                           "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                         }
E                       }
E                     ],
E                     "name": "vmssueaa0Nic",
E                     "networkSecurityGroup": {
E                       "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_update_instance_percent_000001/providers/Microsoft.Network/networkSecurityGroups/vmss-update-instance-percentNSG",
E                       "resourceGroup": "cli_test_vmss_update_instance_percent_000001"
E                     },
E                     "primary": true
E                   }
E                 ]
E               },
E               "osProfile": {
E                 "adminUsername": "testadmin",
E                 "allowExtensionOperations": true,
E                 "computerNamePrefix": "vmss-upd",
E                 "linuxConfiguration": {
E                   "disablePasswordAuthentication": false,
E                   "enableVMAgentPlatformUpdates": true,
E                   "patchSettings": {
E                     "assessmentMode": "ImageDefault",
E                     "patchMode": "ImageDefault"
E                   },
E                   "provisionVMAgent": true
E                 },
E                 "requireGuestProvisionSignal": true,
E                 "secrets": []
E               },
E               "storageProfile": {
E                 "imageReference": {
E                   "offer": "CentOS",
E                   "publisher": "OpenLogic",
E                   "sku": "7.5",
E                   "version": "latest"
E                 },
E                 "osDisk": {
E                   "caching": "ReadWrite",
E                   "createOption": "FromImage",
E                   "deleteOption": "Delete",
E                   "diskSizeGB": 30,
E                   "managedDisk": {
E                     "storageAccountType": "Premium_LRS"
E                   },
E                   "osType": "Linux"
E                 }
E               },
E               "timeCreated": "2026-02-23T04:46:12.1860441+00:00"
E             },
E             "zoneBalance": false
E           }

src/azure-cli-testsdk/azure/cli/testsdk/checkers.py:36: JMESPathCheckAssertionError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:14340

@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Feb 26, 2026

️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

@yonzhan
Copy link
Collaborator

yonzhan commented Feb 26, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the az vmss command group core commands (create, show, update, wait) from SDK-based implementation to AAZ-based implementation, following Azure CLI's ongoing effort to standardize on AAZ for compute resources.

Changes:

  • Migrated vmss show, vmss update, and vmss wait command registrations from SDK-based to AAZ-based implementation
  • Updated create_vmss function to use AAZ-based get_vmss_by_aaz instead of SDK-based get_vmss
  • Modified Guest Attestation Extension installation logic to work with AAZ dictionary responses (camelCase keys)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/azure-cli/azure/cli/command_modules/vm/commands.py Moved vmss create/show/update/wait command registrations from SDK operation group to AAZ-based command group without operation_group
src/azure-cli/azure/cli/command_modules/vm/custom.py Updated create_vmss to use get_vmss_by_aaz and modified extension installation code to handle AAZ dictionary responses

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +4131 to +4158
vmss = get_vmss_by_aaz(cmd, resource_group_name, vmss_name)
vmss['virtualMachineProfile']['storageProfile']['imageReference'] = None
os_type = vmss.get('virtualMachineProfile', {}).get('storageProfile', {}).get('osDisk', {}).get('osType')
if os_type == 'Linux':
publisher = 'Microsoft.Azure.Security.LinuxAttestation'
if vmss.virtual_machine_profile.storage_profile.os_disk.os_type == 'Windows':
elif os_type == 'Windows':
publisher = 'Microsoft.Azure.Security.WindowsAttestation'
version = _normalize_extension_version(cmd.cli_ctx, publisher, 'GuestAttestation', None, vmss.location)
ext = VirtualMachineScaleSetExtension(name='GuestAttestation',
publisher=publisher,
type_properties_type='GuestAttestation',
protected_settings=None,
type_handler_version=version,
settings=None,
auto_upgrade_minor_version=True,
provision_after_extensions=None,
enable_automatic_upgrade=not disable_integrity_monitoring_autoupgrade)
if not vmss.virtual_machine_profile.extension_profile:
vmss.virtual_machine_profile.extension_profile = VirtualMachineScaleSetExtensionProfile(extensions=[])
vmss.virtual_machine_profile.extension_profile.extensions.append(ext)
else:
publisher = ''
version = _normalize_extension_version(cmd.cli_ctx, publisher, 'GuestAttestation',
None, vmss.get('location'))
ext = {
'name': 'GuestAttestation',
'auto_upgrade_minor_version': True,
'enable_automatic_upgrade': not disable_integrity_monitoring_autoupgrade,
'publisher': publisher,
'type_handler_version': version,
'type': 'GuestAttestation'
}
if not vmss.get('virtualMachineProfile', {}).get('extensionProfile'):
vmss['virtualMachineProfile']['extensionProfile'] = {'extensions': []}
vmss['virtualMachineProfile']['extensionProfile']['extensions'].append(ext)
try:
LongRunningOperation(cmd.cli_ctx)(client.virtual_machine_scale_sets.begin_create_or_update(
resource_group_name, vmss_name, vmss))
from .operations.vmss import VMSSCreate
vmss['resource_group'] = resource_group_name
vmss['vm_scale_set_name'] = vmss_name
_create_vmss = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss)
LongRunningOperation(cmd.cli_ctx)(_create_vmss)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VMSS object retrieved from get_vmss_by_aaz returns camelCase keys (e.g., 'virtualMachineProfile'), but AAZ Create/Update commands expect snake_case argument names. Before passing the vmss dictionary to VMSSCreate, you must convert it using the convert_show_result_to_snake_case function.

Compare this to the update_vmss function (lines 4587-4593) which correctly performs this conversion:

from .operations.vmss import convert_show_result_to_snake_case
vmss = vmss_convert_show_result_to_snake_case(vmss)

Without this conversion, the AAZ command will fail to properly map the dictionary keys to its argument schema, potentially causing the operation to fail or produce incorrect results.

Copilot uses AI. Check for mistakes.
@william051200
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

if (is_trusted_launch or is_confidential_vm) and enable_integrity_monitoring:
client = _compute_client_factory(cmd.cli_ctx)
vmss = client.virtual_machine_scale_sets.get(resource_group_name, vmss_name)
vmss.virtual_machine_profile.storage_profile.image_reference = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask where the logic for this line is implemented?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is at line 4138
vmss['virtualMachineProfile']['storageProfile']['imageReference'] = None

Comment on lines +4148 to +4155
ext = {
'name': 'GuestAttestation',
'autoUpgradeMinorVersion': True,
'enableAutomaticUpgrade': not disable_integrity_monitoring_autoupgrade,
'publisher': publisher,
'typeHandlerVersion': version,
'type': 'GuestAttestation'
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add the properties back whose values are None.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Auto-Assign Auto assign by bot Compute az vm/vmss/image/disk/snapshot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants