Skip to content

Conversation

@huiii99
Copy link
Member

@huiii99 huiii99 commented Jan 27, 2026

Related command
az vmss extension list
az vmss extension show
az vmss extension delete
az vmss extension set
az vmss extension upgrade

Description
Migrate az vmss extension commands from hand written sdk to aaz.
aaz: Azure/aaz#932

Testing Guide

History Notes


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

@huiii99 huiii99 requested a review from zhoxing-ms as a code owner January 27, 2026 06:10
Copilot AI review requested due to automatic review settings January 27, 2026 06:10
@azure-client-tools-bot-prd
Copy link

azure-client-tools-bot-prd bot commented Jan 27, 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
Type Test Case Error Message Line
Failed test_network_watcher_packet_capture_vmss_as_target self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fdf4de08560>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fdf54665ca0>
command = 'vmss create -g cli_test_nw_packet_capture_vmss_as_target000001 --name vmssForPcap --image Canonical:UbuntuServer:18.04-LTS:latest --location westcentralus --admin-username azureuser --generate-ssh-keys --upgrade-policy-mode Automatic'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.12/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = InvalidArgumentValueError("Can't resolve the version of 'Canonical:UbuntuServer:18.04-LTS'")
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception InvalidArgumentValueError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <azure.cli.command_modules.network.tests.latest.test_network_commands.NetworkWatcherScenarioTest testMethod=test_network_watcher_packet_capture_vmss_as_target>
resource_group = 'cli_test_nw_packet_capture_vmss_as_target000001'
resource_group_location = 'westcentralus'

    @mock.patch('azure.cli.command_modules.vm.actions.get_thread_count', mock_thread_count)
    @ResourceGroupPreparer(name_prefix='cli_test_nw_packet_capture_vmss_as_target', location='westcentralus')
    @AllowLargeResponse()
    def test_network_watcher_packet_capture_vmss_as_target(self, resource_group, resource_group_location):
    
        self.kwargs.update({
            'loc': resource_group_location,
            'vmss': 'vmssForPcap',
            'capture': 'captureVmss',
            'capture1': 'captureVMSS1',
            'capture2': 'captureVMSS2'
        })
>       self.cmd('vmss create -g {rg} --name {vmss} --image Canonical:UbuntuServer:18.04-LTS:latest --location {loc} --admin-username azureuser --generate-ssh-keys --upgrade-policy-mode Automatic')

src/azure-cli/azure/cli/command_modules/network/tests/latest/test_network_commands.py:7715: 
 
 
 
 
                                    
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:315: in in_process_execute
    raise ex.exception
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:657: in execute
    self.validation(expanded_arg)
env/lib/python3.12/site-packages/knack/invocation.py:111: in validation
    self.validate_cmd_level(parsed_ns, cmd_validator)
src/azure-cli-core/azure/cli/core/commands/init.py:918: in validate_cmd_level
    cmd_validator(**self.build_kwargs(cmd_validator, ns))
src/azure-cli/azure/cli/command_modules/vm/validators.py:1799: in process_vmss_create_namespace
    validate_vm_create_storage_profile(cmd, namespace, for_scale_set=True)
src/azure-cli/azure/cli/command_modules/vm/validators.py:391: in validate_vm_create_storage_profile
    image_type = parse_image_argument(cmd, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/validators.py:262: in parse_image_argument
    image_plan = get_image_plan_info_if_exists(cmd, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/validators.py:319: in get_image_plan_info_if_exists
    image_version = get_latest_image_version(cmd.cli_ctx, namespace.location, namespace.os_publisher,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     _ 

cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fdf4d81d5e0>
location = 'westcentralus', publisher = 'Canonical', offer = 'UbuntuServer'
sku = '18.04-LTS', edge_zone = None

    def _get_latest_image_version(cli_ctx, location, publisher, offer, sku, edge_zone=None):
        from azure.cli.core.azclierror import InvalidArgumentValueError
        if edge_zone is not None:
            from azure.cli.core.commands.client_factory import get_mgmt_service_client
            from azure.cli.core.profiles import ResourceType
            edge_zone_client = get_mgmt_service_client(cli_ctx, ResourceType.MGMT_COMPUTE).virtual_machine_images_edge_zone
            top_one = edge_zone_client.list(location, edge_zone, publisher, offer, sku, top=1, orderby='name desc')
            if not top_one:
                raise InvalidArgumentValueError("Can't resolve the version of '{}:{}:{}:{}'"
                                                .format(publisher, offer, sku, edge_zone))
        else:
            top_one = _compute_client_factory(cli_ctx).virtual_machine_images.list(location,
                                                                                   publisher,
                                                                                   offer,
                                                                                   sku,
                                                                                   top=1,
                                                                                   orderby='name desc')
            if not top_one:
>               raise InvalidArgumentValueError("Can't resolve the version of '{}:{}:{}'".format(publisher, offer, sku))
E               azure.cli.core.azclierror.InvalidArgumentValueError: Can't resolve the version of 'Canonical:UbuntuServer:18.04-LTS'

src/azure-cli/azure/cli/command_modules/vm/_actions.py:324: InvalidArgumentValueError
src/azure-cli/azure/cli/command_modules/network/tests/latest/test_network_commands.py:7702
❌3.13
Type Test Case Error Message Line
Failed test_network_watcher_packet_capture_vmss_as_target self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fdc7d509310>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fdc83ca1bd0>
command = 'vmss create -g cli_test_nw_packet_capture_vmss_as_target000001 --name vmssForPcap --image Canonical:UbuntuServer:18.04-LTS:latest --location westcentralus --admin-username azureuser --generate-ssh-keys --upgrade-policy-mode Automatic'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.13/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = InvalidArgumentValueError("Can't resolve the version of 'Canonical:UbuntuServer:18.04-LTS'")
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception InvalidArgumentValueError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <azure.cli.command_modules.network.tests.latest.test_network_commands.NetworkWatcherScenarioTest testMethod=test_network_watcher_packet_capture_vmss_as_target>
resource_group = 'cli_test_nw_packet_capture_vmss_as_target000001'
resource_group_location = 'westcentralus'

    @mock.patch('azure.cli.command_modules.vm.actions.get_thread_count', mock_thread_count)
    @ResourceGroupPreparer(name_prefix='cli_test_nw_packet_capture_vmss_as_target', location='westcentralus')
    @AllowLargeResponse()
    def test_network_watcher_packet_capture_vmss_as_target(self, resource_group, resource_group_location):
    
        self.kwargs.update({
            'loc': resource_group_location,
            'vmss': 'vmssForPcap',
            'capture': 'captureVmss',
            'capture1': 'captureVMSS1',
            'capture2': 'captureVMSS2'
        })
>       self.cmd('vmss create -g {rg} --name {vmss} --image Canonical:UbuntuServer:18.04-LTS:latest --location {loc} --admin-username azureuser --generate-ssh-keys --upgrade-policy-mode Automatic')

src/azure-cli/azure/cli/command_modules/network/tests/latest/test_network_commands.py:7715: 
 
 
 
 
                                    
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:315: in in_process_execute
    raise ex.exception
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:657: in execute
    self.validation(expanded_arg)
env/lib/python3.13/site-packages/knack/invocation.py:111: in validation
    self.validate_cmd_level(parsed_ns, cmd_validator)
src/azure-cli-core/azure/cli/core/commands/init.py:918: in validate_cmd_level
    cmd_validator(**self.build_kwargs(cmd_validator, ns))
src/azure-cli/azure/cli/command_modules/vm/validators.py:1799: in process_vmss_create_namespace
    validate_vm_create_storage_profile(cmd, namespace, for_scale_set=True)
src/azure-cli/azure/cli/command_modules/vm/validators.py:391: in validate_vm_create_storage_profile
    image_type = parse_image_argument(cmd, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/validators.py:262: in parse_image_argument
    image_plan = get_image_plan_info_if_exists(cmd, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/validators.py:319: in get_image_plan_info_if_exists
    image_version = get_latest_image_version(cmd.cli_ctx, namespace.location, namespace.os_publisher,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     _ 

cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fdc7ceb2490>
location = 'westcentralus', publisher = 'Canonical', offer = 'UbuntuServer'
sku = '18.04-LTS', edge_zone = None

    def _get_latest_image_version(cli_ctx, location, publisher, offer, sku, edge_zone=None):
        from azure.cli.core.azclierror import InvalidArgumentValueError
        if edge_zone is not None:
            from azure.cli.core.commands.client_factory import get_mgmt_service_client
            from azure.cli.core.profiles import ResourceType
            edge_zone_client = get_mgmt_service_client(cli_ctx, ResourceType.MGMT_COMPUTE).virtual_machine_images_edge_zone
            top_one = edge_zone_client.list(location, edge_zone, publisher, offer, sku, top=1, orderby='name desc')
            if not top_one:
                raise InvalidArgumentValueError("Can't resolve the version of '{}:{}:{}:{}'"
                                                .format(publisher, offer, sku, edge_zone))
        else:
            top_one = _compute_client_factory(cli_ctx).virtual_machine_images.list(location,
                                                                                   publisher,
                                                                                   offer,
                                                                                   sku,
                                                                                   top=1,
                                                                                   orderby='name desc')
            if not top_one:
>               raise InvalidArgumentValueError("Can't resolve the version of '{}:{}:{}'".format(publisher, offer, sku))
E               azure.cli.core.azclierror.InvalidArgumentValueError: Can't resolve the version of 'Canonical:UbuntuServer:18.04-LTS'

src/azure-cli/azure/cli/command_modules/vm/_actions.py:324: InvalidArgumentValueError
src/azure-cli/azure/cli/command_modules/network/tests/latest/test_network_commands.py:7702
️✔️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_vmss_application_enable_automatic_upgrade self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fa8cf8d0c80>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fa8d0f71280>
command = 'vm application set -g cli_test_test_vm_vmss_application_enable_automatic_upgrade000001 -n vm000002 --app-version-ids ...rs/Microsoft.Compute/galleries/MyGallery/applications/MySecondApp/versions/1.0.1 --enable-automatic-upgrade True False'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.12/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = ResourceNotFoundError("(ApplicationNotFound) The gallery application '/subscriptions/00000000-0000-0000-0000-000000000...s/1.0.0' is not available. Verify that all fields in the application profile are correct.\nTarget: applicationProfile")
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception ResourceNotFoundError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.VMVMSSAddApplicationTestScenario testMethod=test_vm_vmss_application_enable_automatic_upgrade>
resource_group = 'cli_test_test_vm_vmss_application_enable_automatic_upgrade000001'

    @AllowLargeResponse()
    @ResourceGroupPreparer(name_prefix='cli_test_test_vm_vmss_application_enable_automatic_upgrade', location='australiacentral')
    def test_vm_vmss_application_enable_automatic_upgrade(self, resource_group):
        self.kwargs.update({
            'vm': self.create_random_name('vm', 10),
            'subnet': self.create_random_name('subnet', 15),
            'vnet': self.create_random_name('vnet', 15),
            'vmss': self.create_random_name('vmss', 10),
            'vid1': '/subscriptions/{sub}/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0'.format(
                sub=self.get_subscription_id()
            ),
            'vid2': '/subscriptions/{sub}/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MySecondApp/versions/1.0.1'.format(
                sub=self.get_subscription_id()
            )
        })
        curr_dir = os.path.dirname(os.path.realpath(file))
        health_extension_file = os.path.join(curr_dir, 'health_extension.json').replace('\', '\\')
        self.kwargs['extension_file'] = health_extension_file
        self.cmd('vm create -g {rg} -n {vm} --image ubuntu2204 --size Standard_B2ms --subnet {subnet} --vnet-name {vnet} --admin-password Password001! --nsg-rule NONE')
        self.cmd('vm extension set --name  ApplicationHealthLinux --publisher Microsoft.ManagedServices --version 1.0 --resource-group {rg} --vm-name {vm} --settings {extension_file}')
        self.cmd('network vnet subnet update -g {rg} --vnet-name {vnet} -n {subnet} --default-outbound-access false')
>       self.cmd('vm application set -g {rg} -n {vm} --app-version-ids {vid1} {vid2} --enable-automatic-upgrade True False', checks=[
            self.check('applicationProfile.galleryApplications[0].enableAutomaticUpgrade', True),
            self.check('applicationProfile.galleryApplications[1].enableAutomaticUpgrade', False)
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13160: 
 
                                       
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:315: in in_process_execute
    raise ex.exception
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:669: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:737: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:717: in run_job
    result = LongRunningOperation(cmd_copy.cli_ctx, 'Starting {}'.format(cmd_copy.name))(result)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:1088: in call
    raise exception
src/azure-cli-core/azure/cli/core/commands/init.py:1075: in call
    result = poller.result()
             ^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/poller.py:108: in result
    self.wait(timeout)
env/lib/python3.12/site-packages/azure/core/tracing/decorator.py:119: in wrapper_use_tracer
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/poller.py:130: in wait
    raise self.exception
src/azure-cli-core/azure/cli/core/aaz/poller.py:83: in start
    for polling_method in self.polling_generator:
                          ^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:7809: in execute_operations
    yield self.VirtualMachinesCreateOrUpdate(ctx=self.ctx)()
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:7940: in call
    return self.on_error(session.http_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
                             

self = <azure.cli.command_modules.vm.aaz.latest.vm.__cmds.Update.VirtualMachinesCreateOrUpdate object at 0x7fa8ce4d4b60>
response = RequestsTransportResponse: 404 , Content-Type: application/json; charset=utf-8

    def on_error(self, response):
        """ handle errors in response
        """
        # raise common http errors
        error_type = self.error_map.get(response.status_code)
        if error_type:
>           raise error_type(response=response)
E           azure.core.exceptions.ResourceNotFoundError: (ApplicationNotFound) The gallery application '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0' is not available. Verify that all fields in the application profile are correct.
E           Code: ApplicationNotFound
E           Message: The gallery application '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0' is not available. Verify that all fields in the application profile are correct.
E           Target: applicationProfile

src/azure-cli-core/azure/cli/core/aaz/_operation.py:324: ResourceNotFoundError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13138
❌3.13
Type Test Case Error Message Line
Failed test_vm_vmss_application_enable_automatic_upgrade self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f6bff905350>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f6c02221590>
command = 'vm application set -g cli_test_test_vm_vmss_application_enable_automatic_upgrade000001 -n vm000002 --app-version-ids ...rs/Microsoft.Compute/galleries/MyGallery/applications/MySecondApp/versions/1.0.1 --enable-automatic-upgrade True False'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.13/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:135: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = ResourceNotFoundError("(ApplicationNotFound) The gallery application '/subscriptions/00000000-0000-0000-0000-000000000...s/1.0.0' is not available. Verify that all fields in the application profile are correct.\nTarget: applicationProfile")
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception ResourceNotFoundError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <latest.test_vm_commands.VMVMSSAddApplicationTestScenario testMethod=test_vm_vmss_application_enable_automatic_upgrade>
resource_group = 'cli_test_test_vm_vmss_application_enable_automatic_upgrade000001'

    @AllowLargeResponse()
    @ResourceGroupPreparer(name_prefix='cli_test_test_vm_vmss_application_enable_automatic_upgrade', location='australiacentral')
    def test_vm_vmss_application_enable_automatic_upgrade(self, resource_group):
        self.kwargs.update({
            'vm': self.create_random_name('vm', 10),
            'subnet': self.create_random_name('subnet', 15),
            'vnet': self.create_random_name('vnet', 15),
            'vmss': self.create_random_name('vmss', 10),
            'vid1': '/subscriptions/{sub}/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0'.format(
                sub=self.get_subscription_id()
            ),
            'vid2': '/subscriptions/{sub}/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MySecondApp/versions/1.0.1'.format(
                sub=self.get_subscription_id()
            )
        })
        curr_dir = os.path.dirname(os.path.realpath(file))
        health_extension_file = os.path.join(curr_dir, 'health_extension.json').replace('\', '\\')
        self.kwargs['extension_file'] = health_extension_file
        self.cmd('vm create -g {rg} -n {vm} --image ubuntu2204 --size Standard_B2ms --subnet {subnet} --vnet-name {vnet} --admin-password Password001! --nsg-rule NONE')
        self.cmd('vm extension set --name  ApplicationHealthLinux --publisher Microsoft.ManagedServices --version 1.0 --resource-group {rg} --vm-name {vm} --settings {extension_file}')
        self.cmd('network vnet subnet update -g {rg} --vnet-name {vnet} -n {subnet} --default-outbound-access false')
>       self.cmd('vm application set -g {rg} -n {vm} --app-version-ids {vid1} {vid2} --enable-automatic-upgrade True False', checks=[
            self.check('applicationProfile.galleryApplications[0].enableAutomaticUpgrade', True),
            self.check('applicationProfile.galleryApplications[1].enableAutomaticUpgrade', False)
        ])

src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13160: 
 
                                       
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:315: in in_process_execute
    raise ex.exception
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:669: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:737: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:717: in run_job
    result = LongRunningOperation(cmd_copy.cli_ctx, 'Starting {}'.format(cmd_copy.name))(result)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:1088: in call
    raise exception
src/azure-cli-core/azure/cli/core/commands/init.py:1075: in call
    result = poller.result()
             ^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/poller.py:108: in result
    self.wait(timeout)
env/lib/python3.13/site-packages/azure/core/tracing/decorator.py:119: in wrapper_use_tracer
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/aaz/poller.py:130: in wait
    raise self.exception
src/azure-cli-core/azure/cli/core/aaz/poller.py:83: in start
    for polling_method in self.polling_generator:
                          ^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:13793: in execute_operations
    yield self.VirtualMachinesCreateOrUpdate(ctx=self.ctx)()
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__cmds.py:13924: in call
    return self.on_error(session.http_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
                             

self = <azure.cli.command_modules.vm.aaz.latest.vm.__cmds.Update.VirtualMachinesCreateOrUpdate object at 0x7f6bff8f38c0>
response = RequestsTransportResponse: 404 , Content-Type: application/json; charset=utf-8

    def on_error(self, response):
        """ handle errors in response
        """
        # raise common http errors
        error_type = self.error_map.get(response.status_code)
        if error_type:
>           raise error_type(response=response)
E           azure.core.exceptions.ResourceNotFoundError: (ApplicationNotFound) The gallery application '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0' is not available. Verify that all fields in the application profile are correct.
E           Code: ApplicationNotFound
E           Message: The gallery application '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/galleryappaccount/providers/Microsoft.Compute/galleries/MyGallery/applications/MyFirstApp/versions/1.0.0' is not available. Verify that all fields in the application profile are correct.
E           Target: applicationProfile

src/azure-cli-core/azure/cli/core/aaz/_operation.py:324: ResourceNotFoundError
azure/cli/command_modules/vm/tests/latest/test_vm_commands.py:13138

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

azure-client-tools-bot-prd bot commented Jan 27, 2026

⚠️AzureCLI-BreakingChangeTest
⚠️vm
rule cmd_name rule_message suggest_message
⚠️ 1011 - SubgroupAdd compute sub group compute added

@yonzhan
Copy link
Collaborator

yonzhan commented Jan 27, 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

Migrates az vmss extension commands away from handwritten Compute SDK usage toward AAZ-based implementations.

Changes:

  • Reworked VMSS extension operations in custom.py to use AAZ VMSS update flow and an AAZ rolling-upgrade command wrapper.
  • Added generated AAZ command group/code for VMSS extension rolling upgrade.
  • Adjusted the VMSS extension scenario test VMSS create parameters (image + SKU) for the test run.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py Updates the VMSS creation used by VMSS extension scenario tests.
src/azure-cli/azure/cli/command_modules/vm/custom.py Moves VMSS extension delete/show/list/set/upgrade logic toward AAZ-based flows.
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/compute/virtual_machine_scale_set/_extension_rolling_upgrade.py Adds generated AAZ command to start VMSS extension rolling upgrade.
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/compute/virtual_machine_scale_set/init.py Exposes the generated VMSS rolling-upgrade command module.
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/compute/virtual_machine_scale_set/__cmd_group.py Declares the generated AAZ command group for compute virtual machine scale set.
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/compute/init.py Adds generated AAZ compute package init for command group wiring.
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/compute/__cmd_group.py Declares the generated AAZ top-level compute command group.

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

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.

4 participants