From 9ae1f1ab643c734bb48f3fee461775cccb57b318 Mon Sep 17 00:00:00 2001 From: Qi Pan <43341456+Pan-Qi@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:28:15 +1000 Subject: [PATCH] AI add compute parameter --- .../azure/cli/command_modules/vm/_params.py | 41 ++++++++++++------- .../cli/command_modules/vm/_validators.py | 8 ++++ .../azure/cli/command_modules/vm/custom.py | 13 +++++- .../vm/tests/latest/test_vm_commands.py | 25 +++++++++++ 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/_params.py b/src/azure-cli/azure/cli/command_modules/vm/_params.py index cdd3e204932..a43eb7b92b8 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_params.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_params.py @@ -782,20 +782,8 @@ def load_arguments(self, _): help='Specify the policy for availability zone placement of the virtual machine scale set. ' 'When set to Auto, the platform automatically selects the availability zones.' ) - c.argument( - 'include_zones', - nargs='+', - help='Specify a list of availability zones that must be considered for placement when ' - '--zone-placement-policy is set to Auto. ' - 'If not specified, all availability zones in the region are considered.' - ) - c.argument( - 'exclude_zones', - nargs='+', - help='Specify a list of availability zones that must be excluded from placement when ' - '--zone-placement-policy is set to Auto. ' - 'If not specified, no availability zones are excluded.' - ) + c.argument('include_zones', nargs='+', min_api='2024-07-01', help='Specify a list of availability zones that must be considered for placement when --zone-placement-policy is set to Auto. If not specified, all availability zones in the region are considered. This argument cannot be used with --exclude-zones.') + c.argument('exclude_zones', nargs='+', min_api='2024-07-01', help='Specify a list of availability zones that must be excluded from placement when --zone-placement-policy is set to Auto. If not specified, no availability zones are excluded. This argument cannot be used with --include-zones.') c.argument( 'max_zone_count', type=int, @@ -868,6 +856,31 @@ def load_arguments(self, _): c.argument('skuprofile_vmsizes', nargs='+', min_api='2024-07-01', help='A list of VM sizes in the scale set. See https://azure.microsoft.com/pricing/details/virtual-machines/ for size info.') c.argument('skuprofile_allostrat', options_list=['--skuprofile-allocation-strategy', '--sku-allocat-strat'], arg_type=get_enum_type(['LowestPrice', 'CapacityOptimized', 'Prioritized']), min_api='2024-07-01', help='Allocation strategy for vm sizes in SKU profile.') c.argument('skuprofile_rank', nargs='+', min_api='2024-11-01', help='A list for ranks associated with the SKU profile vm sizes.') + c.argument( + 'zone_placement_policy', + arg_type=get_enum_type(['Auto']), + min_api='2025-11-01', + help='Specify the policy for availability zone placement of the virtual machine scale set. ' + 'When set to Auto, the platform automatically selects the availability zones.' + ) + c.argument( + 'include_zones', + nargs='+', + min_api='2025-11-01', + help='Specify a list of availability zones that must be considered for placement when ' + '--zone-placement-policy is set to Auto. ' + 'If not specified, all availability zones in the region are considered. ' + 'This argument cannot be used with --exclude-zones.' + ) + c.argument( + 'exclude_zones', + nargs='+', + min_api='2025-11-01', + help='Specify a list of availability zones that must be excluded from placement when ' + '--zone-placement-policy is set to Auto. ' + 'If not specified, no availability zones are excluded. ' + 'This argument cannot be used with --include-zones.' + ) c.argument( 'max_zone_count', type=int, diff --git a/src/azure-cli/azure/cli/command_modules/vm/_validators.py b/src/azure-cli/azure/cli/command_modules/vm/_validators.py index 4380eaf38cc..3055bf25fda 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_validators.py @@ -1961,6 +1961,7 @@ def validate_vmss_update_namespace(cmd, namespace): # pylint: disable=unused-ar _validate_vmss_update_automatic_repairs(cmd, namespace) _validate_capacity_reservation_group(cmd, namespace) _validate_vm_vmss_update_ephemeral_placement(cmd, namespace) + _validate_vmss_auto_zone_placement_include_exclude(namespace) # endregion @@ -2706,7 +2707,14 @@ def _validate_vmss_create_host_group(cmd, namespace): ) +def _validate_vmss_auto_zone_placement_include_exclude(namespace): + if getattr(namespace, 'include_zones', None) and getattr(namespace, 'exclude_zones', None): + raise MutuallyExclusiveArgumentError('You can only specify one of --include-zones and --exclude-zones') + + def _validate_vmss_create_auto_zone_placement(namespace): + _validate_vmss_auto_zone_placement_include_exclude(namespace) + zpp = getattr(namespace, 'zone_placement_policy', None) zones = getattr(namespace, 'zones', None) zone_balance = getattr(namespace, 'zone_balance', None) diff --git a/src/azure-cli/azure/cli/command_modules/vm/custom.py b/src/azure-cli/azure/cli/command_modules/vm/custom.py index 944f3ba348a..4690f60279b 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -4647,7 +4647,8 @@ def update_vmss(cmd, resource_group_name, name, license_type=None, no_wait=False wire_server_mode=None, imds_mode=None, add_proxy_agent_extension=None, wire_server_access_control_profile_reference_id=None, imds_access_control_profile_reference_id=None, enable_automatic_zone_balancing=None, - automatic_zone_balancing_strategy=None, automatic_zone_balancing_behavior=None, max_zone_count=None, + automatic_zone_balancing_strategy=None, automatic_zone_balancing_behavior=None, + zone_placement_policy=None, include_zones=None, exclude_zones=None, max_zone_count=None, instance_percent_policy=None, max_instance_percent=None, **kwargs): from .operations.vmss_vms import convert_show_result_to_snake_case as vmss_vms_convert_show_result_to_snake_case from .operations.vmss import convert_show_result_to_snake_case as vmss_convert_show_result_to_snake_case @@ -5102,6 +5103,16 @@ def _output(self, *args, **kwargs): if zone_balance is not None: vmss["zone_balance"] = zone_balance + if zone_placement_policy is not None or include_zones is not None or exclude_zones is not None: + if vmss.get("placement", None) is None: + vmss["placement"] = {} + if zone_placement_policy is not None: + vmss["placement"]["zone_placement_policy"] = zone_placement_policy + if include_zones is not None: + vmss["placement"]["include_zones"] = include_zones + if exclude_zones is not None: + vmss["placement"]["exclude_zones"] = exclude_zones + vmss["resource_group"] = resource_group_name vmss["vm_scale_set_name"] = name vmss["no_wait"] = no_wait diff --git a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py index 4905dbfca9a..1bd33bdb008 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/test_vm_commands.py @@ -14471,6 +14471,31 @@ def test_vmss_zone_placement_policy_validation_zones_conflict(self): '--vm-sku {vm_sku} ' ) + def test_vmss_zone_placement_policy_validation_include_exclude_conflict(self): + self.kwargs.update({ + 'rg': 'rgtest', + 'vmss': 'vmss-zone-placement-invalid', + 'location': 'eastus2', + 'image': 'MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest', + 'admin_username': 'testadmin', + 'admin_password': 'testPassword0', + 'vm_sku': 'Standard_B2ms' + }) + + with self.assertRaisesRegex(Exception, 'You can only specify one of --include-zones and --exclude-zones'): + self.cmd( + 'vmss create -g {rg} -n {vmss} -l {location} ' + '--instance-count 3 ' + '--image {image} ' + '--admin-username {admin_username} ' + '--admin-password {admin_password} ' + '--upgrade-policy-mode Manual ' + '--zone-placement-policy Auto ' + '--include-zones 1 ' + '--exclude-zones 2 ' + '--vm-sku {vm_sku} ' + ) + @ResourceGroupPreparer(name_prefix='cli_test_vmss_zone_placement_overprovision_') def test_vmss_zone_placement_policy_validation_overprovision_uniform(self, resource_group): self.kwargs.update({