Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1a5fbbd
Application Gateway for Containers add-on commands
JackStromberg Nov 4, 2025
d7f5571
Update HISTORY.rst
JackStromberg Nov 4, 2025
88d3432
Update HISTORY.rst
JackStromberg Nov 4, 2025
e242cd0
Merge branch 'main' into agc-addon
JackStromberg Nov 4, 2025
3e75d7c
Update HISTORY.rst
JackStromberg Nov 4, 2025
ad4b754
Update HISTORY.rst
JackStromberg Nov 4, 2025
0e8b3ba
Update src/aks-preview/azext_aks_preview/managed_cluster_decorator.py
JackStromberg Nov 4, 2025
c40c3af
tests
JackStromberg Nov 11, 2025
7ee983e
Merge branch 'main' into agc-addon
JackStromberg Nov 12, 2025
e2a2c16
enable params
JackStromberg Nov 13, 2025
11aed85
parameter length linter exclusion
JackStromberg Nov 13, 2025
5998eb8
Enable gateway api
JackStromberg Dec 12, 2025
78a9f91
Missing update and passing test
JackStromberg Dec 12, 2025
055a3f7
Linter exception
JackStromberg Dec 12, 2025
47208c6
Linter - take 2
JackStromberg Dec 12, 2025
9520b8f
Update HISTORY.rst
JackStromberg Dec 12, 2025
560f0f5
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
JackStromberg Dec 12, 2025
3a4d8ba
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
JackStromberg Dec 12, 2025
8f01427
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
JackStromberg Dec 12, 2025
b5d36b8
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
JackStromberg Dec 12, 2025
f4692ea
Update src/aks-preview/azext_aks_preview/custom.py
JackStromberg Dec 12, 2025
7f34b1c
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
JackStromberg Dec 12, 2025
4dba0d8
Update custom.py
JackStromberg Dec 12, 2025
51e4e34
Merge branch 'Azure:main' into agc-addon
JackStromberg Dec 15, 2025
e967940
update test results
JackStromberg Dec 15, 2025
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
5 changes: 5 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ If there is no rush to release a new version, please just add a description of t
To release a new version, please select a new version number (usually plus 1 to last patch version, X.Y.Z -> Major.Minor.Patch, more details in `\doc <https://semver.org/>`_), and then add a new section named as the new version number in this file, the content should include the new modifications and everything from the *Pending* section. Finally, update the `VERSION` variable in `setup.py` with this new version number.

Pending
+++++++
* Add add-on support for `ApplicationLoadBalancer` (Application Gateway for Containers)
- `az aks applicationloadbalancer enable`: Enable Application Load Balancer add-on for an existing cluster.
- `az aks applicationloadbalancer disable`: Disable Application Load Balancer add-on for an existing cluster.
- `az aks applicationloadbalancer update`: Update Application Load Balancer add-on for an existing cluster.

19.0.0b10
+++++++
Expand Down
9 changes: 8 additions & 1 deletion src/aks-preview/azext_aks_preview/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@
CONST_DISK_DRIVER_V2 = "v2"

# consts for addons
# application load balancer (Application Gateway for Containers)
CONST_APPLICATION_LOAD_BALANCER_ADDON_NAME = "applicationLoadBalancer"

# http application routing
CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME = "httpApplicationRouting"

Expand Down Expand Up @@ -224,6 +227,7 @@

# all supported addons
ADDONS = {
"application-load-balancer": CONST_APPLICATION_LOAD_BALANCER_ADDON_NAME,
"http_application_routing": CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME,
"monitoring": CONST_MONITORING_ADDON_NAME,
"virtual-node": CONST_VIRTUAL_NODE_ADDON_NAME,
Expand Down Expand Up @@ -254,7 +258,10 @@
"- enable Azure policy. The Azure Policy add-on for AKS enables at-scale enforcements and safeguards on "
"your clusters in a centralized, consistent manner.\nLearn more at aka.ms/aks/policy."
),
CONST_INGRESS_APPGW_ADDON_NAME: "- enable Application Gateway Ingress Controller addon (PREVIEW).",
CONST_APPLICATION_LOAD_BALANCER_ADDON_NAME: (
"- enable Application Load Balancer (Application Gateway for Containers) addon (PREVIEW)."
),
CONST_INGRESS_APPGW_ADDON_NAME: "- enable Application Gateway Ingress Controller addon.",
CONST_CONFCOM_ADDON_NAME: "- enable confcom addon, this will enable SGX device plugin by default (PREVIEW).",
CONST_OPEN_SERVICE_MESH_ADDON_NAME: "- enable Open Service Mesh addon (PREVIEW).",
CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME: "- enable Azure Keyvault Secrets Provider addon.",
Expand Down
35 changes: 31 additions & 4 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@
- monitoring : turn on Log Analytics monitoring. Uses the Log Analytics Default Workspace if it exists, else creates one. Specify "--workspace-resource-id" to use an existing workspace. If monitoring addon is enabled --no-wait argument will have no effect
- virtual-node : enable AKS Virtual Node. Requires --aci-subnet-name to provide the name of an existing subnet for the Virtual Node to use. aci-subnet-name must be in the same vnet which is specified by --vnet-subnet-id (required as well).
- azure-policy : enable Azure policy. The Azure Policy add-on for AKS enables at-scale enforcements and safeguards on your clusters in a centralized, consistent manner. Required if enabling deployment safeguards. Learn more at aka.ms/aks/policy.
- ingress-appgw : enable Application Gateway Ingress Controller addon (PREVIEW).
- application-load-balancer : enable the Application Load Balancer (Application Gateway for Containers) addon (PREVIEW).
- ingress-appgw : enable Application Gateway Ingress Controller addon.
- confcom : enable confcom addon, this will enable SGX device plugin by default(PREVIEW).
- open-service-mesh : enable Open Service Mesh addon (PREVIEW).
- gitops : enable GitOps (PREVIEW).
Expand Down Expand Up @@ -2779,7 +2780,8 @@
virtual-node - enable AKS Virtual Node. Requires --subnet-name to provide the name of an existing subnet for the Virtual Node to use.
azure-policy - enable Azure policy. The Azure Policy add-on for AKS enables at-scale enforcements and safeguards on your clusters in a centralized, consistent manner.
Learn more at aka.ms/aks/policy.
ingress-appgw - enable Application Gateway Ingress Controller addon (PREVIEW).
application-load-balancer - enable the Application Load Balancer (Application Gateway for Containers) addon (PREVIEW).
ingress-appgw - enable Application Gateway Ingress Controller addon.
open-service-mesh - enable Open Service Mesh addon (PREVIEW).
gitops - enable GitOps (PREVIEW).
azure-keyvault-secrets-provider - enable Azure Keyvault Secrets Provider addon.
Expand Down Expand Up @@ -2939,7 +2941,8 @@
virtual-node - enable AKS Virtual Node. Requires --subnet-name to provide the name of an existing subnet for the Virtual Node to use.
azure-policy - enable Azure policy. The Azure Policy add-on for AKS enables at-scale enforcements and safeguards on your clusters in a centralized, consistent manner.
Learn more at aka.ms/aks/policy.
ingress-appgw - enable Application Gateway Ingress Controller addon (PREVIEW).
application-load-balancer - enable the Application Load Balancer (Application Gateway for Containers) addon (PREVIEW).
ingress-appgw - enable Application Gateway Ingress Controller addon.
open-service-mesh - enable Open Service Mesh addon (PREVIEW).
gitops - enable GitOps (PREVIEW).
azure-keyvault-secrets-provider - enable Azure Keyvault Secrets Provider addon.
Expand Down Expand Up @@ -3612,9 +3615,33 @@
text: az aks mesh disable-istio-cni --resource-group MyResourceGroup --name MyManagedCluster
"""

helps['aks applicationloadbalancer'] = """
type: group
short-summary: Commands to manage Application Load Balancer (Application Gateway for Containers) addon.
long-summary: A group of commands to manage Application Load Balancer (Application Gateway for Containers) in given cluster.
"""

helps['aks applicationloadbalancer enable'] = """
type: command
short-summary: Enable Application Load Balancer (Application Gateway for Containers) addon.
long-summary: This command enables Application Load Balancer in given cluster.
"""

helps['aks applicationloadbalancer update'] = """
type: command
short-summary: Update Application Load Balancer (Application Gateway for Containers) addon.
long-summary: This command is used to make a put operation on the Application Load Balancer in a given cluster.
"""

helps['aks applicationloadbalancer disable'] = """
type: command
short-summary: Disable Application Load Balancer (Application Gateway for Containers) addon.
long-summary: This command disables Application Load Balancer (Application Gateway for Containers) in given cluster.
"""

helps['aks approuting'] = """
type: group
short-summary: Commands to manage App Routing aadon.
short-summary: Commands to manage App Routing addon.
long-summary: A group of commands to manage App Routing in given cluster.
"""

Expand Down
18 changes: 18 additions & 0 deletions src/aks-preview/azext_aks_preview/addonconfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ def update_addons(
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
operation_group="managed_clusters",
)
ManagedClusterIngressProfileApplicationLoadBalancer = cmd.get_models(
"ManagedClusterIngressProfileApplicationLoadBalancer",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
operation_group="managed_clusters",
)
ManagedClusterIngressProfileWebAppRouting = cmd.get_models(
"ManagedClusterIngressProfileWebAppRouting",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -261,6 +266,19 @@ def update_addons(

# for each addons argument
for addon_arg in addon_args:
if addon_arg == "applicationloadbalancer":
# application load balancer settings are in ingress profile, not addon profile
if instance.ingress_profile is None:
instance.ingress_profile = ManagedClusterIngressProfile()
if instance.ingress_profile.application_load_balancer is None:
instance.ingress_profile.application_load_balancer = (
ManagedClusterIngressProfileApplicationLoadBalancer()
)

instance.ingress_profile.application_load_balancer.enabled = enable

continue

if addon_arg == "web_application_routing":
# web app routing settings are in ingress profile, not addon profile, so deal
# with it separately
Expand Down
8 changes: 8 additions & 0 deletions src/aks-preview/azext_aks_preview/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,14 @@ def load_command_table(self, _):
g.custom_command("complete", "aks_mesh_upgrade_complete", supports_no_wait=True)
g.custom_command("rollback", "aks_mesh_upgrade_rollback", supports_no_wait=True)

# AKS applicationloadbalancer (Application Gateway for Containers) commands
with self.command_group(
"aks applicationloadbalancer", managed_clusters_sdk, client_factory=cf_managed_clusters
) as g:
g.custom_command("enable", "aks_applicationloadbalancer_enable")
g.custom_command("disable", "aks_applicationloadbalancer_disable", confirmation=True)
g.custom_command("update", "aks_applicationloadbalancer_update")

# AKS approuting commands
with self.command_group(
"aks approuting", managed_clusters_sdk, client_factory=cf_managed_clusters
Expand Down
105 changes: 105 additions & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2663,6 +2663,12 @@ def aks_addon_list(cmd, client, resource_group_name, name):
mc.ingress_profile.web_app_routing and
mc.ingress_profile.web_app_routing.enabled
)
elif addon_name == "application-load-balancer":
enabled = bool(
mc.ingress_profile and
mc.ingress_profile.application_load_balancer and
mc.ingress_profile.application_load_balancer.enabled
)
else:
if addon_name == "virtual-node":
addon_key += os_type
Expand Down Expand Up @@ -2699,6 +2705,20 @@ def aks_addon_show(cmd, client, resource_group_name, name, addon):
"config": mc.ingress_profile.web_app_routing,
}

# application-load-balancer is a special case, the configuration is stored in a separate profile
if addon == "application-load-balancer":
if (
not mc.ingress_profile and
not mc.ingress_profile.application_load_balancer and
Comment thread
JackStromberg marked this conversation as resolved.
Comment on lines +2717 to +2718
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The logic in this condition uses and instead of or, which will cause it to always evaluate to False. The condition should check if any of these are falsy (None or False), not if all of them are falsy. This should be:

if (
    not mc.ingress_profile or
    not mc.ingress_profile.application_load_balancer or
    not mc.ingress_profile.application_load_balancer.enabled
):

This matches the pattern used for web_application_routing above at lines 2700-2704.

Suggested change
not mc.ingress_profile and
not mc.ingress_profile.application_load_balancer and
not mc.ingress_profile or
not mc.ingress_profile.application_load_balancer or

Copilot uses AI. Check for mistakes.
not mc.ingress_profile.application_load_balancer.enabled
):
raise InvalidArgumentValueError(f'Addon "{addon}" is not enabled in this cluster.')
return {
"name": addon,
"api_key": addon_key,
"config": mc.ingress_profile.application_load_balancer,
}

# normal addons
if not mc.addon_profiles or addon_key not in mc.addon_profiles or not mc.addon_profiles[addon_key].enabled:
raise InvalidArgumentValueError(f'Addon "{addon}" is not enabled in this cluster.')
Expand Down Expand Up @@ -3095,6 +3115,11 @@ def _update_addons(cmd, # pylint: disable=too-many-branches,too-many-statements
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
operation_group="managed_clusters",
)
ManagedClusterIngressProfileApplicationLoadBalancer = cmd.get_models(
"ManagedClusterIngressProfileApplicationLoadBalancer",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
operation_group="managed_clusters",
)
ManagedClusterIngressProfileWebAppRouting = cmd.get_models(
"ManagedClusterIngressProfileWebAppRouting",
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
Expand All @@ -3110,6 +3135,16 @@ def _update_addons(cmd, # pylint: disable=too-many-branches,too-many-statements

# for each addons argument
for addon_arg in addon_args:
if addon_arg == "applicationloadbalancer":
# application load balancer routing settings are in ingress profile, not addon profile
if instance.ingress_profile is None:
instance.ingress_profile = ManagedClusterIngressProfile()
if instance.ingress_profile.application_load_balancer is None:
instance.ingress_profile.application_load_balancer = ManagedClusterIngressProfileApplicationLoadBalancer()
instance.ingress_profile.application_load_balancer.enabled = enable

continue

if addon_arg == "web_application_routing":
# web app routing settings are in ingress profile, not addon profile, so deal
# with it separately
Expand Down Expand Up @@ -4114,6 +4149,47 @@ def _aks_mesh_update(
return aks_update_decorator.update_mc(mc)


def aks_applicationloadbalancer_enable(
cmd,
client,
resource_group_name,
name
):
return _aks_applicationloadbalancer_update(
cmd,
client,
resource_group_name,
name,
enable_application_load_balancer=True)


def aks_applicationloadbalancer_disable(
cmd,
client,
resource_group_name,
name
):
return _aks_applicationloadbalancer_update(
cmd,
client,
resource_group_name,
name,
enable_application_load_balancer=False)
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The aks_applicationloadbalancer_disable function should pass disable_application_load_balancer=True instead of enable_application_load_balancer=False. The decorator's update_application_load_balancer_profile method checks for both enable_application_load_balancer and disable_application_load_balancer parameters separately (lines 6654-6655 in managed_cluster_decorator.py). Setting enable_application_load_balancer=False would result in no operation being performed. This is also related to the missing disable_application_load_balancer parameter in the _aks_applicationloadbalancer_update function signature.

Copilot uses AI. Check for mistakes.


def aks_applicationloadbalancer_update(
cmd,
client,
resource_group_name,
name
):
return _aks_applicationloadbalancer_update(
cmd,
client,
resource_group_name,
name)


def aks_approuting_enable(
cmd,
client,
Expand Down Expand Up @@ -4246,6 +4322,35 @@ def aks_approuting_zone_list(
raise CLIError('App routing addon is not enabled')


# pylint: disable=unused-argument
def _aks_applicationloadbalancer_update(
cmd,
client,
resource_group_name,
name,
enable_application_load_balancer=None
Comment thread
JackStromberg marked this conversation as resolved.
Outdated
):
from azure.cli.command_modules.acs._consts import DecoratorEarlyExitException
from azext_aks_preview.managed_cluster_decorator import AKSPreviewManagedClusterUpdateDecorator

raw_parameters = locals()

aks_update_decorator = AKSPreviewManagedClusterUpdateDecorator(
cmd=cmd,
client=client,
raw_parameters=raw_parameters,
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
)

try:
mc = aks_update_decorator.fetch_mc()
mc = aks_update_decorator.update_application_load_balancer_profile(mc)
except DecoratorEarlyExitException:
return None

return aks_update_decorator.update_mc(mc)


# pylint: disable=unused-argument
def _aks_approuting_update(
cmd,
Expand Down
57 changes: 57 additions & 0 deletions src/aks-preview/azext_aks_preview/managed_cluster_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3432,6 +3432,13 @@ def get_attach_zones(self) -> bool:
"""
return self.raw_param.get("attach_zones")

def get_enable_application_load_balancer(self) -> bool:
"""Obtain the value of enable_application_load_balancer.

:return: bool
"""
return self.raw_param.get("enable_application_load_balancer")

def get_enable_app_routing(self) -> bool:
"""Obtain the value of enable_app_routing.

Expand Down Expand Up @@ -4032,6 +4039,23 @@ def set_up_storage_profile(self, mc: ManagedCluster) -> ManagedCluster:

return mc

def set_up_ingress_application_load_balancer(self, mc: ManagedCluster) -> ManagedCluster:
"""Set up application load balancer profile in ingress profile for the ManagedCluster object.

:return: the ManagedCluster object
"""
self._ensure_mc(mc)

addons = self.context.get_enable_addons()
if "application-load-balancer" in addons or self.context.get_enable_application_load_balancer():
if mc.ingress_profile is None:
mc.ingress_profile = self.models.ManagedClusterIngressProfile() # pylint: disable=no-member
mc.ingress_profile.application_load_balancer = (
self.models.ManagedClusterIngressProfileApplicationLoadBalancer(enabled=True) # pylint: disable=no-member
)

return mc

def set_up_ingress_web_app_routing(self, mc: ManagedCluster) -> ManagedCluster:
"""Set up web app routing profile in ingress profile for the ManagedCluster object.

Expand Down Expand Up @@ -4741,6 +4765,8 @@ def construct_mc_profile_preview(self, bypass_restore_defaults: bool = False) ->
mc = self.set_up_kms_pmk_and_cmk(mc)
# set up cluster snapshot
mc = self.set_up_creationdata_of_cluster_snapshot(mc)
# set up application load balancer profile
mc = self.set_up_ingress_application_load_balancer(mc)
# set up app routing profile
mc = self.set_up_ingress_web_app_routing(mc)
# set up gateway api profile
Expand Down Expand Up @@ -6610,6 +6636,37 @@ def update_node_provisioning_default_pools(self, mc: ManagedCluster) -> ManagedC

return mc

def update_application_load_balancer_profile(self, mc: ManagedCluster) -> ManagedCluster:
"""Update application load balancer (Application Gateway for Containers) profile for the ManagedCluster object.

:return: the ManagedCluster object
"""
self._ensure_mc(mc)

# get parameters from context
enable_application_load_balancer = self.context.get_enable_application_load_balancer()

# update ManagedCluster object with application load balancer settings
mc.ingress_profile = (
mc.ingress_profile or
self.models.ManagedClusterIngressProfile() # pylint: disable=no-member
)
mc.ingress_profile.application_load_balancer = (
mc.ingress_profile.application_load_balancer or
self.models.ManagedClusterIngressProfileApplicationLoadBalancer() # pylint: disable=no-member
)
if enable_application_load_balancer is not None:
if mc.ingress_profile.application_load_balancer.enabled == enable_application_load_balancer:
error_message = (
"Application Load Balancer (Application Gateway for Containers) is already enabled.\n"
if enable_application_load_balancer
else "Application Load Balancer (Application Gateway for Containers) is already disabled.\n"
)
raise CLIError(error_message)
mc.ingress_profile.application_load_balancer.enabled = enable_application_load_balancer

return mc

# pylint: disable=too-many-branches
def update_app_routing_profile(self, mc: ManagedCluster) -> ManagedCluster:
"""Update app routing profile for the ManagedCluster object.
Expand Down
Loading