Skip to content

Commit 05fc657

Browse files
author
Wen Huang
committed
feat: support --node-vm-size on nodepool update for VMSS pool resize
Enable changing the VM size (SKU) of an existing VMSS-based agent pool via `az aks nodepool update --node-vm-size <new-size>`. The RP performs a rolling upgrade (surge new nodes, drain old, delete old) to replace nodes with the new VM size. This preview feature requires: - AFEC registration: Microsoft.ContainerService/AgentPoolVMSSResize - RP internal toggle: enable-agentpool-vmsize-resize Changes: - agentpool_decorator.py: add update_vm_size() for VMSS pools and call it in update_agentpool_profile_preview() - _params.py: mark --node-vm-size as is_preview for nodepool update - _help.py: update help text and add VMSS resize example - test_agentpool_decorator.py: add unit tests for update_vm_size
1 parent fb5c19f commit 05fc657

4 files changed

Lines changed: 78 additions & 1 deletion

File tree

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2478,7 +2478,7 @@
24782478
short-summary: Set the localDNS Profile for a nodepool with a JSON config file.
24792479
- name: --node-vm-size -s
24802480
type: string
2481-
short-summary: VM size for Kubernetes nodes. Only configurable when updating the autoscale settings of a VirtualMachines node pool.
2481+
short-summary: VM size for Kubernetes nodes. For VMSS pools, changing this triggers a rolling upgrade to replace nodes with the new size (preview). For VirtualMachines pools, only configurable when updating autoscale settings.
24822482
- name: --upgrade-strategy
24832483
type: string
24842484
short-summary: Upgrade strategy for the node pool. Allowed values are "Rolling" or "BlueGreen". Default is "Rolling".
@@ -2513,6 +2513,8 @@
25132513
text: az aks nodepool update --mode System -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster
25142514
- name: Update cluster autoscaler vm size, min-count and max-count for virtual machines node pool
25152515
text: az aks nodepool update -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster --update-cluster-autoscaler --node-vm-size "Standard_D2s_v3" --min-count 2 --max-count 4
2516+
- name: Resize VM size for a VMSS node pool (preview, requires AFEC registration)
2517+
text: az aks nodepool update -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster --node-vm-size Standard_D4s_v3
25162518
- name: Update a node pool with blue-green upgrade settings
25172519
text: az aks nodepool update -g MyResourceGroup -n nodepool1 --cluster-name MyManagedCluster --drain-batch-size 50% --drain-timeout-bg 5 --batch-soak-duration 10 --final-soak-duration 10
25182520
"""

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,7 @@ def load_arguments(self, _):
22052205
"node_vm_size",
22062206
options_list=["--node-vm-size", "-s"],
22072207
completer=get_vm_size_completion_list,
2208+
is_preview=True,
22082209
)
22092210
c.argument(
22102211
"gpu_driver",

src/aks-preview/azext_aks_preview/agentpool_decorator.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,6 +1848,30 @@ def update_fips_image(self, agentpool: AgentPool) -> AgentPool:
18481848

18491849
return agentpool
18501850

1851+
def update_vm_size(self, agentpool: AgentPool) -> AgentPool:
1852+
"""Update VM size for the AgentPool object.
1853+
1854+
Allows changing the VM size (SKU) of an existing VMSS-based agent pool.
1855+
The RP will perform a rolling upgrade (surge new nodes, drain old, delete old)
1856+
to replace nodes with the new VM size.
1857+
1858+
Note: This is only for VMSS pools. VMs pools handle VM size changes through
1859+
the autoscaler update path (update_auto_scaler_properties_vms).
1860+
1861+
:return: the AgentPool object
1862+
"""
1863+
self._ensure_agentpool(agentpool)
1864+
1865+
# Skip for VirtualMachines pools - they handle VM size via autoscaler path
1866+
if self.context.get_vm_set_type() == CONST_VIRTUAL_MACHINES:
1867+
return agentpool
1868+
1869+
node_vm_size = self.context.raw_param.get("node_vm_size")
1870+
if node_vm_size:
1871+
agentpool.vm_size = node_vm_size
1872+
1873+
return agentpool
1874+
18511875
def update_localdns_profile(self, agentpool: AgentPool) -> AgentPool:
18521876
"""Update local DNS profile for the AgentPool object if provided via --localdns-config."""
18531877
self._ensure_agentpool(agentpool)
@@ -1910,6 +1934,9 @@ def update_agentpool_profile_preview(self, agentpools: List[AgentPool] = None) -
19101934
# update ssh access
19111935
agentpool = self.update_ssh_access(agentpool)
19121936

1937+
# update vm size for VMSS pools
1938+
agentpool = self.update_vm_size(agentpool)
1939+
19131940
# update local DNS profile
19141941
agentpool = self.update_localdns_profile(agentpool)
19151942

src/aks-preview/azext_aks_preview/tests/latest/test_agentpool_decorator.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,47 @@ def common_update_fips_image(self):
26502650
with self.assertRaises(MutuallyExclusiveArgumentError):
26512651
dec_3.update_fips_image(agentpool_2)
26522652

2653+
def common_update_vm_size(self):
2654+
# Test case 1: No node_vm_size provided (should not change agentpool)
2655+
dec_1 = AKSPreviewAgentPoolUpdateDecorator(
2656+
self.cmd,
2657+
self.client,
2658+
{"node_vm_size": None},
2659+
self.resource_type,
2660+
self.agentpool_decorator_mode,
2661+
)
2662+
# fail on passing the wrong agentpool object
2663+
with self.assertRaises(CLIInternalError):
2664+
dec_1.update_vm_size(None)
2665+
2666+
agentpool_1 = self.create_initialized_agentpool_instance(
2667+
vm_size="Standard_D2s_v3"
2668+
)
2669+
dec_1.context.attach_agentpool(agentpool_1)
2670+
dec_agentpool_1 = dec_1.update_vm_size(agentpool_1)
2671+
ground_truth_agentpool_1 = self.create_initialized_agentpool_instance(
2672+
vm_size="Standard_D2s_v3"
2673+
)
2674+
self.assertEqual(dec_agentpool_1, ground_truth_agentpool_1)
2675+
2676+
# Test case 2: node_vm_size provided (should update agentpool)
2677+
dec_2 = AKSPreviewAgentPoolUpdateDecorator(
2678+
self.cmd,
2679+
self.client,
2680+
{"node_vm_size": "Standard_D4s_v3"},
2681+
self.resource_type,
2682+
self.agentpool_decorator_mode,
2683+
)
2684+
agentpool_2 = self.create_initialized_agentpool_instance(
2685+
vm_size="Standard_D2s_v3"
2686+
)
2687+
dec_2.context.attach_agentpool(agentpool_2)
2688+
dec_agentpool_2 = dec_2.update_vm_size(agentpool_2)
2689+
ground_truth_agentpool_2 = self.create_initialized_agentpool_instance(
2690+
vm_size="Standard_D4s_v3"
2691+
)
2692+
self.assertEqual(dec_agentpool_2, ground_truth_agentpool_2)
2693+
26532694
def common_update_upgrade_strategy(self):
26542695
# Test case 1: No upgrade strategy provided (should not change agentpool)
26552696
dec_1 = AKSPreviewAgentPoolUpdateDecorator(
@@ -2990,6 +3031,9 @@ def test_update_vtpm(self):
29903031
def test_update_fips_image(self):
29913032
self.common_update_fips_image()
29923033

3034+
def test_update_vm_size(self):
3035+
self.common_update_vm_size()
3036+
29933037
def test_update_upgrade_strategy(self):
29943038
self.common_update_upgrade_strategy()
29953039

@@ -3086,6 +3130,9 @@ def test_update_vtpm(self):
30863130
def test_update_fips_image(self):
30873131
self.common_update_fips_image()
30883132

3133+
def test_update_vm_size(self):
3134+
self.common_update_vm_size()
3135+
30893136
def test_update_upgrade_strategy(self):
30903137
self.common_update_upgrade_strategy()
30913138

0 commit comments

Comments
 (0)