Skip to content

Comments

[ARM] Deployment Stacks initial 2025-07-01 API version support#32777

Open
kalbert312 wants to merge 45 commits intoAzure:devfrom
kalbert312:kylea/stacks-2025-07-01
Open

[ARM] Deployment Stacks initial 2025-07-01 API version support#32777
kalbert312 wants to merge 45 commits intoAzure:devfrom
kalbert312:kylea/stacks-2025-07-01

Conversation

@kalbert312
Copy link
Member

@kalbert312 kalbert312 commented Feb 11, 2026

Related command
az stack

Description

Bumps the package version of azure-mgmt-resources to 24.0.0 which splits out deployments related resource types into smaller packages. Bumps azure-mgmt-resources-deploymentstacks to 1.0.0 that includes the new 2025-07-01 API version.

The default API version for az stack commands is now 2025-07-01. This API version ships with support for stacks extensible resource management and what-if support. What-if commands will be available in a future AzCLI release.

Extensible resource management only manages and deletes extensible resources that are deployed with extensions that implement the v2 extensibility contract. Microsoft Graph's v1 extension is not supported for this feature, for example. If an older API version is used, extensible resource management is effectively a no-op and will retain any existing management status behind the scenes. This was done to prevent unexpected behavioral changes to users upgrading their AzCLI that may be deploying resources that would be affected by this new feature.

The --resources-without-delete-support parameter modifies the behavior of stacks when trying to delete resources managed by the stack. By default, a stack will enter a failed state if this type of error occurs, but can be set to detach the resource(s) instead.

The --validation-level parameter controls the level of preflight validation performed on a stack. By default, the full validation level Provider is used, but there are a couple of other reduced modes that can be used.

Scaffolding for the upcoming what-if commands is added, but no new commands are added yet.

Testing Guide
See DeploymentStacksTest live tests.

History Notes

[ARM] az stack group/sub/mg create/validate: Add --resources-without-delete-support parameter to support defining what happens to resources that do not support deletion when they are no longer managed by the stack
[ARM] az stack group/sub/mg create/validate: Add --validation-level parameter to support specifying validation level for the deployment stack
[ARM] az stack group/sub/mg delete: Add --resources-without-delete-support parameter to support defining what happens to resources that do not support deletion when they are no longer managed by the stack


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

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

azure-client-tools-bot-prd bot commented Feb 11, 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_nw_connection_monitor_v2_creation self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f62b666c140>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f62c2755a00>
command = 'network watcher connection-monitor create --name cmv2-01 --endpoint-source-name vm2 --endpoint-source-resource-id /su...ndpoint-dest-name bing --endpoint-dest-address bing.com --test-config-name DefaultIcmp --protocol Icmp --tags tag=test'
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:141: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/patches.py:33: in handle_main_exception
    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:682: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:807: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:787: 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:1145: 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/network/aaz/latest/network/watcher/connection_monitor/__cmds.py:466: in execute_operations
    self.pre_operations()
src/azure-cli/azure/cli/command_modules/network/operations/watcher.py:808: in pre_operations
    process_nw_cm_v2_create_namespace(self)
src/azure-cli/azure/cli/command_modules/network/operations/watcher.py:583: in process_nw_cm_v2_create_namespace
    resource_api_version = resolve_api_version(resource_client,
src/azure-cli/azure/cli/command_modules/network/validators.py:32: in resolve_api_version
    provider = rcf.providers.get(resource_provider_namespace)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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/v2025_04_01/operations/operations.py:3634: 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/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.yaml(host='management.azure.com', port=443) at 0x7f62c2289dc0>
 = 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/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.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/providers/Microsoft.Compute?api-version=2025-04-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/providers/Microsoft.Compute?api-version=2024-11-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 = <azure.cli.command_modules.network.tests.latest.test_nw_connection_monitor.NWConnectionMonitorScenarioTest testMethod=test_nw_connection_monitor_v2_creation>
resource_group = 'connection_monitor_v2_test_000001'
resource_group_location = 'westus'

    @ResourceGroupPreparer(name_prefix='connection_monitor_v2_test
', location='westus')
    @AllowLargeResponse()
    def test_nw_connection_monitor_v2_creation(self, resource_group, resource_group_location):
        # create a V2 connection monitor with --location and TCP configuration
        self.prepare_connection_monitor_v2_env(resource_group, resource_group_location)
    
        # create a v2 connection monitor without --location and ICMP configuration
>       self.cmd('network watcher connection-monitor create '
                 '--name cmv2-01 '
                 '--endpoint-source-name vm2 '
                 '--endpoint-source-resource-id {vm2_id} '
                 '--endpoint-dest-name bing '
                 '--endpoint-dest-address bing.com '
                 '--test-config-name DefaultIcmp '
                 '--protocol Icmp --tags tag=test',
                 checks=[
                     self.check('tags', {'tag': 'test'})
                 ])

src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_connection_monitor.py:66: 
 
 
 
 
 
 
 
                                 
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)
                                       _ 

self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f62b666c140>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f62c2755a00>
command = 'network watcher connection-monitor create --name cmv2-01 --endpoint-source-name vm2 --endpoint-source-resource-id /su...ndpoint-dest-name bing --endpoint-dest-address bing.com --test-config-name DefaultIcmp --protocol Icmp --tags tag=test'
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
            self.output = stdout_buf.getvalue()
            self.applog = logging_buf.getvalue()
    
        except CannotOverwriteExistingCassetteException as ex:
>           raise AssertionError(ex)
E           AssertionError: Can't overwrite existing cassette ('/mnt/vss/_work/1/s/src/azure-cli/azure/cli/command_modules/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.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/providers/Microsoft.Compute?api-version=2025-04-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/providers/Microsoft.Compute?api-version=2024-11-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path']
E           Matchers failed :
E           _custom_request_query_matcher - assertion failure :
E           None

src/azure-cli-testsdk/azure/cli/testsdk/base.py:308: AssertionError
src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_connection_monitor.py:58
❌3.13
Type Test Case Error Message Line
Failed test_nw_connection_monitor_v2_creation self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f57fafe29c0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f57f9c8e490>
command = 'network watcher connection-monitor create --name cmv2-01 --endpoint-source-name vm2 --endpoint-source-resource-id /su...ndpoint-dest-name bing --endpoint-dest-address bing.com --test-config-name DefaultIcmp --protocol Icmp --tags tag=test'
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:141: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/patches.py:33: in handle_main_exception
    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:682: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:807: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:787: 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:1145: 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/network/aaz/latest/network/watcher/connection_monitor/__cmds.py:466: in execute_operations
    self.pre_operations()
src/azure-cli/azure/cli/command_modules/network/operations/watcher.py:808: in pre_operations
    process_nw_cm_v2_create_namespace(self)
src/azure-cli/azure/cli/command_modules/network/operations/watcher.py:583: in process_nw_cm_v2_create_namespace
    resource_api_version = resolve_api_version(resource_client,
src/azure-cli/azure/cli/command_modules/network/validators.py:32: in resolve_api_version
    provider = rcf.providers.get(resource_provider_namespace)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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/v2025_04_01/operations/operations.py:3634: 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/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.yaml(host='management.azure.com', port=443) at 0x7f57fa1f6900>
 = 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/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.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/providers/Microsoft.Compute?api-version=2025-04-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/providers/Microsoft.Compute?api-version=2024-11-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 = <azure.cli.command_modules.network.tests.latest.test_nw_connection_monitor.NWConnectionMonitorScenarioTest testMethod=test_nw_connection_monitor_v2_creation>
resource_group = 'connection_monitor_v2_test_000001'
resource_group_location = 'westus'

    @ResourceGroupPreparer(name_prefix='connection_monitor_v2_test
', location='westus')
    @AllowLargeResponse()
    def test_nw_connection_monitor_v2_creation(self, resource_group, resource_group_location):
        # create a V2 connection monitor with --location and TCP configuration
        self.prepare_connection_monitor_v2_env(resource_group, resource_group_location)
    
        # create a v2 connection monitor without --location and ICMP configuration
>       self.cmd('network watcher connection-monitor create '
                 '--name cmv2-01 '
                 '--endpoint-source-name vm2 '
                 '--endpoint-source-resource-id {vm2_id} '
                 '--endpoint-dest-name bing '
                 '--endpoint-dest-address bing.com '
                 '--test-config-name DefaultIcmp '
                 '--protocol Icmp --tags tag=test',
                 checks=[
                     self.check('tags', {'tag': 'test'})
                 ])

src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_connection_monitor.py:66: 
 
 
 
 
 
 
 
                                 
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)
                                       _ 

self = <azure.cli.testsdk.base.ExecutionResult object at 0x7f57fafe29c0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7f57f9c8e490>
command = 'network watcher connection-monitor create --name cmv2-01 --endpoint-source-name vm2 --endpoint-source-resource-id /su...ndpoint-dest-name bing --endpoint-dest-address bing.com --test-config-name DefaultIcmp --protocol Icmp --tags tag=test'
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
            self.output = stdout_buf.getvalue()
            self.applog = logging_buf.getvalue()
    
        except CannotOverwriteExistingCassetteException as ex:
>           raise AssertionError(ex)
E           AssertionError: Can't overwrite existing cassette ('/mnt/vss/_work/1/s/src/azure-cli/azure/cli/command_modules/network/tests/latest/recordings/test_nw_connection_monitor_v2_creation.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/providers/Microsoft.Compute?api-version=2025-04-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/providers/Microsoft.Compute?api-version=2024-11-01>).
E           Matchers succeeded : ['method', 'scheme', 'host', 'port', 'path']
E           Matchers failed :
E           _custom_request_query_matcher - assertion failure :
E           None

src/azure-cli-testsdk/azure/cli/testsdk/base.py:308: AssertionError
src/azure-cli/azure/cli/command_modules/network/tests/latest/test_nw_connection_monitor.py:58
️✔️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
️✔️3.13

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

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

⚠️AzureCLI-BreakingChangeTest
⚠️resource
rule cmd_name rule_message suggest_message
⚠️ 1006 - ParaAdd stack group create cmd stack group create added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack group create cmd stack group create added parameter validation_level
⚠️ 1006 - ParaAdd stack group delete cmd stack group delete added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack group validate cmd stack group validate added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack group validate cmd stack group validate added parameter validation_level
⚠️ 1006 - ParaAdd stack mg create cmd stack mg create added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack mg create cmd stack mg create added parameter validation_level
⚠️ 1006 - ParaAdd stack mg delete cmd stack mg delete added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack mg validate cmd stack mg validate added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack mg validate cmd stack mg validate added parameter validation_level
⚠️ 1006 - ParaAdd stack sub create cmd stack sub create added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack sub create cmd stack sub create added parameter validation_level
⚠️ 1006 - ParaAdd stack sub delete cmd stack sub delete added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack sub validate cmd stack sub validate added parameter resources_without_delete_support
⚠️ 1006 - ParaAdd stack sub validate cmd stack sub validate added parameter validation_level

@yonzhan
Copy link
Collaborator

yonzhan commented Feb 11, 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>

@kalbert312 kalbert312 marked this pull request as ready for review February 19, 2026 19:00
@kalbert312 kalbert312 requested a review from jsntcy as a code owner February 19, 2026 19:00
Copilot AI review requested due to automatic review settings February 19, 2026 19:00
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 updates the Azure CLI deployment stacks module to support the new 2025-07-01 API version, upgrading from beta to stable packages. The changes introduce new parameters for extensible resource management and validation controls, while maintaining backward compatibility.

Changes:

  • Bumped azure-mgmt-resource to 24.0.0 and azure-mgmt-resource-deploymentstacks to 1.0.0 (stable)
  • Added --resources-without-delete-support and --validation-level parameters to stack commands
  • Refactored code to use direct model imports and new API enums instead of client factory models
  • Scaffolded what-if commands (commented out, not ready for March 2026 release)

Reviewed changes

Copilot reviewed 21 out of 30 changed files in this pull request and generated no comments.

Show a summary per file
File Description
setup.py Updated package versions to stable releases
requirements.py3.*.txt Updated pinned package versions across all platforms
custom.py Major refactoring: removed client factory dependency, updated to use new API models and enums, added what-if command implementations
commands.py Added commented-out what-if command registrations
_params.py Consolidated parameter definitions, added new parameters for extensible resources and validation
_validators.py Added ISO-8601 duration validator for what-if retention intervals
_client_factory.py Added API version parameters to client factories
linter_exclusions.yml Added exclusions for stack commands lacking wait support
test_resource.py Updated tests with new parameters and removed extraneous whitespace
Recording files Updated to reflect new API version responses

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

@kalbert312
Copy link
Member Author

@yanzhudd @zhoxing-ms @jsntcy our team is wanting this to go out for the March release.

@kalbert312
Copy link
Member Author

kalbert312 commented Feb 20, 2026

Hold on merge until this comment is updated. This is OK to merge again (had to fix an issue).

@yanzhudd
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@yanzhudd
Copy link
Contributor

please resolve the ci issues

@kalbert312
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 32777 in repo Azure/azure-cli

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.

3 participants