Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion src/azure-cli/azure/cli/command_modules/vm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
Loading