Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3752bec
add spot max price flag
erinborders Mar 17, 2026
b787769
enable ultra ssd and eviction policy
erinborders Mar 17, 2026
bf3be79
change notes
erinborders Mar 17, 2026
2be46ca
linting
erinborders Mar 17, 2026
ad7b35d
linting
erinborders Mar 17, 2026
72f4df4
test coverage
erinborders Mar 18, 2026
837546f
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 18, 2026
519845c
fix default
erinborders Mar 19, 2026
c2bde65
Merge branch 'Azure:main' into erinborders/machine-preview
erinborders Mar 19, 2026
41fc811
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 19, 2026
601acd9
Merge branch 'erinborders/machine-preview' of https://github.com/erin…
erinborders Mar 19, 2026
4e6cd6d
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 20, 2026
20fef2b
modify test
erinborders Mar 20, 2026
fb1bf72
hardware property name
erinborders Mar 24, 2026
2bf4bd9
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 24, 2026
799f29c
add zones
erinborders Mar 24, 2026
4d42dc5
space
erinborders Mar 24, 2026
47806a9
nodepool zone
erinborders Mar 24, 2026
5712645
multiple zones
erinborders Mar 24, 2026
d7882ce
typo
erinborders Mar 25, 2026
1ab8a94
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 25, 2026
360a345
fix silently discarded zones property
erinborders Mar 26, 2026
e03e118
Merge branch 'main' of https://github.com/erinborders/azure-cli-exten…
erinborders Mar 26, 2026
b3fdfb4
key error
erinborders Mar 26, 2026
32c3206
restore to main
erinborders Mar 30, 2026
e6b60d1
zones argument
erinborders Mar 30, 2026
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
3 changes: 3 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Pending
+++++++
* `az aks create/update`: Add `--enable-app-routing-istio` / `--disable-app-routing-istio` (short: `--enable-ari` / `--disable-ari`) flags to enable or disable Istio as a Gateway API implementation for App Routing.
* `az aks approuting gateway istio enable/disable`: Add new subcommands to enable or disable the Istio Gateway API implementation for App Routing on an existing cluster.
* `az aks machine add`: Add `--spot-max-price` flag support to set the max price (in US Dollars) you are willing to pay for spot instances on a machine.
* `az aks machine add`: Add `--eviction-policy` flag support to set the eviction policy for a machine.
* `az aks machine add`: Add `--enable-ultra-ssd` flag support to enable ultra ssd on a machine.
* Add 'mTLS' as a transit encryption type option for `--acns-transit-encryption-type` in `az aks create/update`

19.0.0b25
Expand Down
9 changes: 9 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -2725,6 +2725,15 @@
- name: --node-public-ip-tags
type: string
short-summary: The ipTags of the machine public IPs.
- name: --spot-max-price
type: number
short-summary: The max price (in US Dollars) you are willing to pay for spot instances.
- name: --enable-ultra-ssd
type: bool
short-summary: Whether to enable UltraSSD.
- name: --eviction-policy
type: string
short-summary: The eviction policy for machine. This cannot be specified unless the priority is 'Spot'. If not specified, the default is 'Delete'.
"""

helps['aks machine update'] = """
Expand Down
15 changes: 15 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2338,6 +2338,21 @@ def load_arguments(self, _):
validator=validate_k8s_version,
help="Version of Kubernetes to use for the machine.",
)
c.argument(
"spot_max_price",
type=float,
validator=validate_spot_max_price,
help="The max price (in US Dollars) you are willing to pay for spot instances."
)
c.argument(
"enable_ultra_ssd",
action="store_true"
)
c.argument(
"eviction_policy",
arg_type=get_enum_type(node_eviction_policies),
validator=validate_eviction_policy,
)

with self.argument_context("aks machine update") as c:
c.argument(
Expand Down
3 changes: 3 additions & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2744,6 +2744,9 @@ def aks_machine_add(
vm_size=None,
kubernetes_version=None,
no_wait=False,
spot_max_price=float("nan"),
enable_ultra_ssd=False,
eviction_policy=None,
):
existedMachine = None
try:
Expand Down
23 changes: 21 additions & 2 deletions src/aks-preview/azext_aks_preview/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,18 @@ def constructMachine(cmd, raw_parameters, machine_name):
)
tags = raw_parameters.get("tags")
priority = raw_parameters.get("priority")
eviction_policy = raw_parameters.get("eviction_policy")
machineProperties = MachineProperties(
tags=tags,
priority=priority,
eviction_policy=eviction_policy,
network=set_machine_network(cmd, raw_parameters),
hardware=set_machine_hardware_profile(cmd, raw_parameters),
kubernetes=set_machine_kubernetes_profile(cmd, raw_parameters),
operating_system=set_machine_os_profile(cmd, raw_parameters)
operating_system=set_machine_os_profile(cmd, raw_parameters),
billing=set_machine_billing_profile(cmd, raw_parameters)
)

Machine = cmd.get_models(
"Machine",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -106,6 +110,7 @@ def constructMachine(cmd, raw_parameters, machine_name):


def set_machine_hardware_profile(cmd, raw_parameters):
enable_ultra_ssd = raw_parameters.get("enable_ultra_ssd")
vm_size = raw_parameters.get("vm_size")
if vm_size is None:
raise RequiredArgumentMissingError(
Expand All @@ -117,7 +122,8 @@ def set_machine_hardware_profile(cmd, raw_parameters):
operation_group="machines"
)
machine_hardware_profile = MachineHardwareProfile(
vm_size=vm_size
vm_size=vm_size,
ultra_ssd_enabled=enable_ultra_ssd
)
return machine_hardware_profile

Expand Down Expand Up @@ -196,3 +202,16 @@ def set_machine_os_profile(cmd, raw_parameters):
enable_fips=enable_fips
)
return machineOSProfile


def set_machine_billing_profile(cmd, raw_parameters):
spot_max_price = raw_parameters.get("spot_max_price")
MachineBillingProfile = cmd.get_models(
"MachineBillingProfile",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
operation_group="machines"
)
machineBillingProfile = MachineBillingProfile(
spot_max_price=spot_max_price
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default value float("nan") is not standard in JSON

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I modeled this off of aks_agentpool_add which also has the spot_max_price property

)
return machineBillingProfile
Original file line number Diff line number Diff line change
Expand Up @@ -2685,6 +2685,84 @@ def test_aks_machines_nodepool(self, resource_group, resource_group_location):
checks=[self.is_empty()],
)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(
random_name_length=17, name_prefix="clitest", location="westus2"
)
def test_aks_machine_add_spot_and_ultra_ssd(self, resource_group, resource_group_location):
aks_name = self.create_random_name("cliakstest", 16)
nodepool_name = self.create_random_name("c", 6)
self.kwargs.update(
{
"resource_group": resource_group,
"location": resource_group_location,
"name": aks_name,
"ssh_key_value": self.generate_ssh_keys(),
"nodepool_name": nodepool_name,
"machine_name": "machinetest1",
"vm_size": "Standard_D4s_v3",
}
)

# create aks cluster
self.cmd(
"aks create "
"--resource-group={resource_group} "
"--name={name} "
"--ssh-key-value={ssh_key_value}",
checks=[
self.check("provisioningState", "Succeeded"),
],
)

# add machines nodepool
self.cmd(
"aks nodepool add "
"--resource-group={resource_group}"
" --cluster-name={name} "
"--name={nodepool_name} "
"--mode=Machines",
checks=[
self.check("provisioningState", "Succeeded"),
self.check("mode", "Machines"),
],
)

# add machine with spot priority, eviction policy, spot-max-price, and ultra ssd
self.cmd(
"aks machine add "
" --resource-group={resource_group} "
" --cluster-name={name} "
" --nodepool-name={nodepool_name} "
" --machine-name={machine_name} "
" --vm-size={vm_size} "
" --zones 1 "
" --priority Spot "
" --eviction-policy Delete "
" --spot-max-price 0.5 "
" --enable-ultra-ssd"
)

# show the machine and verify spot/eviction/ultra-ssd settings
show_cmd = (
"aks machine show "
" --resource-group={resource_group} "
" --cluster-name={name} "
" --nodepool-name={nodepool_name} "
" --machine-name={machine_name} -o json"
)
machine_show = self.cmd(show_cmd).get_output_in_json()
assert machine_show["properties"]["priority"] == "Spot"
assert machine_show["properties"]["evictionPolicy"] == "Delete"
assert machine_show["properties"]["billing"]["spotMaxPrice"] == 0.5
assert machine_show["properties"]["hardware"]["ultraSsdEnabled"] is True

# delete AKS cluster
self.cmd(
"aks delete -g {resource_group} -n {name} --yes --no-wait",
checks=[self.is_empty()],
)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(
random_name_length=17, name_prefix="clitest", location="westus2"
Expand Down
Loading