{Compute} az vm create/ update: Support zone-resilient VM with --zone-movement and cross-zone movement#33242
{Compute} az vm create/ update: Support zone-resilient VM with --zone-movement and cross-zone movement#33242william051200 wants to merge 22 commits intoAzure:devfrom
az vm create/ update: Support zone-resilient VM with --zone-movement and cross-zone movement#33242Conversation
|
Hi @william051200, |
|
| rule | cmd_name | rule_message | suggest_message |
|---|---|---|---|
| sig identity wait | cmd sig identity wait added |
||
| vm create | cmd vm create added parameter zone_movement |
||
| vm update | cmd vm update added parameter zone_movement |
||
| vm update | cmd vm update added parameter zone |
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
|
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). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
There was a problem hiding this comment.
Pull request overview
This PR adds support for zone-resilient VMs by introducing --zone-movement on az vm create / az vm update, and implements cross-zone movement orchestration when updating a VM’s zone.
Changes:
- Add
--zone-movementsupport to VM create/update payloads (resiliencyProfile.zoneMovement.isEnabled). - Implement zone move orchestration on
az vm update --zone ...(force deallocate → PUT VM → start). - Regenerate/extend AAZ VM schemas and add a live-only scenario test for zone movement.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/azure-cli/azure/cli/command_modules/vm/custom.py |
Adds zone_movement handling and implements cross-zone move orchestration during vm update. |
src/azure-cli/azure/cli/command_modules/vm/_template_builder.py |
Adds resiliencyProfile.zoneMovement into the ARM template for vm create. |
src/azure-cli/azure/cli/command_modules/vm/_params.py |
Exposes --zone-movement argument for vm create and vm update. |
src/azure-cli/azure/cli/command_modules/vm/operations/vm.py |
Extends snake_case conversion to include resiliencyProfile.zoneMovement. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_create.py |
Updates VM Create AAZ model/version and adds resiliencyProfile schema support. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_update.py |
Updates VM Update AAZ model/version and adds resiliencyProfile schema support. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_show.py |
Updates VM Show AAZ model/version and adds resiliencyProfile schema support. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_wait.py |
Updates VM Wait AAZ resource version and adds resiliencyProfile fields in schema. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_deallocate.py |
Adds --force-deallocate support and updates API version/LRO behavior. |
src/azure-cli/azure/cli/command_modules/vm/aaz/latest/sig/identity/__init__.py |
Exports generated sig identity wait command. |
src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py |
Adds a live-only scenario test for create/update zone movement behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Step 1: Force deallocate the VM | ||
| logger.warning('Changing to zone %s. Force-deallocating VM...', target_zones) | ||
| from .aaz.latest.vm import Deallocate as VMDeallocate |
There was a problem hiding this comment.
These log lines represent normal workflow for a zone move (not an anomalous condition). Using logger.warning will surface as warnings to users and can be noisy; please use logger.info (or logger.debug) for progress messages and reserve warnings for actionable problems.
| c.argument('align_regional_disks_to_vm_zone', options_list=['--align-regional-disks-to-vm-zone', '--align-regional-disks'], arg_type=get_three_state_flag(), min_api='2024-11-01', help='Specify whether the regional disks should be aligned/moved to the VM zone. This is applicable only for VMs with placement property set. Please note that this change is irreversible.') | ||
| c.argument('key_incarnation_id', type=int, min_api='2024-11-01', help='Increase the value of this property allows user to reset the key used for securing communication channel between guest and host.') | ||
| c.argument('security_type', arg_type=get_enum_type(["TrustedLaunch", "Standard", "ConfidentialVM"], default=None), help='Specify the security type of the virtual machine. The value Standard can be used if subscription has feature flag UseStandardSecurityType registered under Microsoft.Compute namespace. Refer to https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/preview-features for steps to enable required feature.') | ||
| c.argument('zone_movement', arg_type=get_three_state_flag(), help='Indicates if zone movement is enabled. By default isEnabled is set to false i.e VM can\'t be moved from one zone to another.') |
There was a problem hiding this comment.
--zone-movement is a service/API-version gated feature (per issue metadata). Without a min_api guard here, the argument will appear in profiles/clouds where the property isn’t supported and will fail at runtime. Add an appropriate min_api (and/or a validator check) to gate the argument.
| c.argument('zone_movement', arg_type=get_three_state_flag(), help='Indicates if zone movement is enabled. By default isEnabled is set to false i.e VM can\'t be moved from one zone to another.') | |
| c.argument('zone_movement', arg_type=get_three_state_flag(), min_api='2024-11-01', help='Indicates if zone movement is enabled. By default isEnabled is set to false i.e VM can\'t be moved from one zone to another.') |
| _aaz_info = { | ||
| "version": "2025-04-01", | ||
| "version": "2025-11-01", | ||
| "resources": [ | ||
| ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachines/{}", "2025-04-01"], | ||
| ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachines/{}", "2025-11-01"], | ||
| ] |
There was a problem hiding this comment.
PR metadata/linked issue indicates a minimum Compute API version of 2025-04-01, but these vm create/update/show operations are pinned to 2025-11-01. Please confirm the minimum required version for zone movement and either keep the API version at the minimum needed (to maximize cloud/profile compatibility) or update the PR description accordingly.
| @live_only() | ||
| @AllowLargeResponse(size_kb=999999) | ||
| @ResourceGroupPreparer(name_prefix='cli_test_vm_zone_movement_', location='eastus2euap') | ||
| def test_vm_zone_movement(self, resource_group): |
There was a problem hiding this comment.
This scenario is marked @live_only(), so it won’t run in the standard recorded test pipeline/CI and won’t protect the feature from regressions. If possible, add a recorded scenario (or a smaller-scope unit/integration test) for zone movement, or document why only live coverage is feasible.
| if zone_change: | ||
| try: | ||
| logger.warning('Updating VM with new zone...') | ||
| create_poller = VMCreate(cli_ctx=cmd.cli_ctx)(command_args=vm) | ||
| LongRunningOperation(cmd.cli_ctx)(create_poller) |
There was a problem hiding this comment.
The zone-change path always blocks on the PUT and start operations via LongRunningOperation, which ignores the command’s --no-wait support (vm update is registered with supports_no_wait=True). Consider rejecting --no-wait when --zone triggers a move, or refactor to preserve no-wait semantics (e.g., return an LRO/poller for the orchestration).
| vm['resiliency_profile'] = { | ||
| 'zone_movement': { | ||
| 'is_enabled': zone_movement | ||
| } | ||
| } |
There was a problem hiding this comment.
Setting vm['resiliency_profile'] = {...} overwrites any existing resiliency_profile fields that may already be present on the VM (from the GET) and could unintentionally drop other resiliency settings on update. Prefer merging into the existing dict (create if missing) and only updating zone_movement.is_enabled.
| vm['resiliency_profile'] = { | |
| 'zone_movement': { | |
| 'is_enabled': zone_movement | |
| } | |
| } | |
| if vm.get("resiliency_profile", None) is None: | |
| vm["resiliency_profile"] = {} | |
| if vm["resiliency_profile"].get("zone_movement", None) is None: | |
| vm["resiliency_profile"]["zone_movement"] = {} | |
| vm["resiliency_profile"]["zone_movement"]["is_enabled"] = zone_movement |
Related command
az vm createaz vm updateaz vm showaz vm deallocateDescription
Resolve #29807
aaz Azure/aaz#992
Testing Guide
Refer to
vm\tests\latest\test_vm_commands.py-test_vm_zone_movementRecording is not being generated due to size too big
History Notes
[Compute]
az vm create/ update: Support zone-resilient VM with--zone-movement[Compute]
az vm update: Support cross-zone movement[Compute]
az vm deallocate: Support vm force deallocate with--force-deallocateThis checklist is used to make sure that common guidelines for a pull request are followed.
The PR title and description has followed the guideline in Submitting Pull Requests.
I adhere to the Command Guidelines.
I adhere to the Error Handling Guidelines.