Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
Pending
+++++++

21.0.0b2
++++++
* `az aks create / update`: Add `--enable-control-plane-metrics` and `az aks update`: `--disable-control-plane-metrics` flags to opt clusters into Azure Monitor managed Prometheus control plane metrics (kube-apiserver, etcd, etc.) via the first-class API property in API version `2026-02-02-preview` (replaces the AFEC-gated preview).

21.0.0b1
++++++
* [BREAKING CHANGE] `az aks create/update`: Remove `--disk-driver-version` option as the `version` field has been removed from the API spec for `ManagedClusterStorageProfileDiskCSIDriver`.
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 @@ -580,6 +580,9 @@
- name: --enable-azure-monitor-metrics
type: bool
short-summary: Enable Azure Monitor Metrics Profile
- name: --enable-control-plane-metrics --enable-cp-metrics
type: bool
short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.
- name: --azure-monitor-workspace-resource-id
type: string
short-summary: Resource ID of the Azure Monitor Workspace
Expand Down Expand Up @@ -1285,6 +1288,9 @@
- name: --enable-azure-monitor-metrics
type: bool
short-summary: Enable Azure Monitor Metrics Profile
- name: --enable-control-plane-metrics --enable-cp-metrics
type: bool
short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.
- name: --azure-monitor-workspace-resource-id
type: string
short-summary: Resource ID of the Azure Monitor Workspace
Expand All @@ -1306,6 +1312,9 @@
- name: --disable-azure-monitor-metrics
type: bool
short-summary: Disable Azure Monitor Metrics Profile. This will delete all DCRA's associated with the cluster, any linked DCRs with the data stream = prometheus-stream and the recording rule groups created by the addon for this AKS cluster.
- name: --disable-control-plane-metrics --disable-cp-metrics
type: bool
short-summary: Disable collection of Azure Monitor managed Prometheus control plane metrics. Leaves Azure Monitor metrics enabled. See aka.ms/aks/controlplane-metrics.
- name: --enable-azure-monitor-app-monitoring
type: bool
short-summary: Enable Azure Monitor Application Monitoring
Expand Down
29 changes: 29 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,16 @@ def load_arguments(self, _):
c.argument("ksm_metric_annotations_allow_list")
c.argument("grafana_resource_id", validator=validate_grafanaresourceid)
c.argument("enable_windows_recording_rules", action="store_true")
c.argument(
"enable_control_plane_metrics",
options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"],
action="store_true",
help=(
"Enable collection of Azure Monitor managed Prometheus control plane metrics for managed "
"cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled "
"(already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics."
),
)
c.argument("enable_azure_monitor_app_monitoring",
is_preview=True,
action="store_true"
Expand Down Expand Up @@ -1596,6 +1606,25 @@ def load_arguments(self, _):
hide=True,
),
)
c.argument(
"enable_control_plane_metrics",
options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"],
action="store_true",
help=(
"Enable collection of Azure Monitor managed Prometheus control plane metrics for managed "
"cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled "
"(already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics."
),
)
c.argument(
"disable_control_plane_metrics",
options_list=["--disable-control-plane-metrics", "--disable-cp-metrics"],
action="store_true",
help=(
"Disable collection of Azure Monitor managed Prometheus control plane metrics. "
"Sets azureMonitorProfile.metrics.controlPlane.enabled=false on the cluster."
),
)
c.argument("enable_azure_monitor_app_monitoring",
action="store_true",
is_preview=True
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 @@ -1136,6 +1136,7 @@ def aks_create(
ksm_metric_annotations_allow_list=None,
grafana_resource_id=None,
enable_windows_recording_rules=False,
enable_control_plane_metrics=False,
# azure monitor profile - app monitoring
enable_azure_monitor_app_monitoring=False,
# opentelemetry parameters
Expand Down Expand Up @@ -1361,6 +1362,8 @@ def aks_update(
enable_windows_recording_rules=False,
disable_azuremonitormetrics=False,
disable_azure_monitor_metrics=False,
enable_control_plane_metrics=False,
disable_control_plane_metrics=False,
# azure monitor profile - app monitoring
enable_azure_monitor_app_monitoring=False,
disable_azure_monitor_app_monitoring=False,
Expand Down
121 changes: 121 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 @@ -2596,6 +2596,91 @@ def get_disable_azure_monitor_metrics(self) -> bool:
"""
return self._get_disable_azure_monitor_metrics(enable_validation=True)

def _get_enable_control_plane_metrics(self, enable_validation: bool = False) -> bool:
"""Internal function to obtain the value of enable_control_plane_metrics.
This function supports the option of enable_validation. When enabled, if both
enable_control_plane_metrics and disable_control_plane_metrics are specified, raise a
MutuallyExclusiveArgumentError. Additionally, --enable-control-plane-metrics requires Azure
Monitor metrics to either already be enabled on the cluster or to be enabled in the same
command via --enable-azure-monitor-metrics.

:return: bool
"""
# Read the original value passed by the command.
enable_control_plane_metrics = self.raw_param.get("enable_control_plane_metrics")
# In create mode, try to read the property value corresponding to the parameter from the `mc` object.
if self.decorator_mode == DecoratorMode.CREATE:
if (
self.mc and
self.mc.azure_monitor_profile and
self.mc.azure_monitor_profile.metrics and
self.mc.azure_monitor_profile.metrics.control_plane
):
enable_control_plane_metrics = self.mc.azure_monitor_profile.metrics.control_plane.enabled
# This parameter does not need dynamic completion.
if enable_validation:
if enable_control_plane_metrics and self._get_disable_control_plane_metrics(False):
raise MutuallyExclusiveArgumentError(
"Cannot specify --enable-control-plane-metrics and --disable-control-plane-metrics "
"at the same time."
)
if enable_control_plane_metrics:
# Reject combining enable-control-plane-metrics with disable-azure-monitor-metrics
# in the same command — the resulting payload would be inconsistent.
if self._get_disable_azure_monitor_metrics(False):
raise MutuallyExclusiveArgumentError(
"Cannot specify --enable-control-plane-metrics together with "
"--disable-azure-monitor-metrics."
)
# Must have Azure Monitor metrics enabled (either already or in this command).
already_enabled = (
self.mc and
self.mc.azure_monitor_profile and
self.mc.azure_monitor_profile.metrics and
self.mc.azure_monitor_profile.metrics.enabled
)
enabling_now = self._get_enable_azure_monitor_metrics(False)
if not already_enabled and not enabling_now:
raise RequiredArgumentMissingError(
"--enable-control-plane-metrics requires Azure Monitor metrics to be enabled. "
"Specify --enable-azure-monitor-metrics or run on a cluster that already has "
"Azure Monitor metrics enabled."
)
Comment thread
davidkydd marked this conversation as resolved.
return enable_control_plane_metrics

def get_enable_control_plane_metrics(self) -> bool:
"""Obtain the value of enable_control_plane_metrics.
This function will verify the parameter by default. If both enable_control_plane_metrics and
disable_control_plane_metrics are specified, raise a MutuallyExclusiveArgumentError.
:return: bool
"""
return self._get_enable_control_plane_metrics(enable_validation=True)

def _get_disable_control_plane_metrics(self, enable_validation: bool = False) -> bool:
"""Internal function to obtain the value of disable_control_plane_metrics.
This function supports the option of enable_validation. When enabled, if both
enable_control_plane_metrics and disable_control_plane_metrics are specified, raise a
MutuallyExclusiveArgumentError.
:return: bool
"""
# Read the original value passed by the command.
disable_control_plane_metrics = self.raw_param.get("disable_control_plane_metrics")
if enable_validation:
if disable_control_plane_metrics and self._get_enable_control_plane_metrics(False):
raise MutuallyExclusiveArgumentError(
"Cannot specify --enable-control-plane-metrics and --disable-control-plane-metrics "
"at the same time."
)
return disable_control_plane_metrics

def get_disable_control_plane_metrics(self) -> bool:
"""Obtain the value of disable_control_plane_metrics.
This function will verify the parameter by default. If both enable_control_plane_metrics and
disable_control_plane_metrics are specified, raise a MutuallyExclusiveArgumentError.
:return: bool
"""
return self._get_disable_control_plane_metrics(enable_validation=True)

def _get_enable_azure_monitor_app_monitoring(self, enable_validation=True) -> bool:
"""Internal function to obtain the value of enable_azure_monitor_app_monitoring.
This function supports the option of enable_validation. When enabled, if both
Expand Down Expand Up @@ -4622,6 +4707,13 @@ def _setup_azure_monitor_metrics(self, mc: ManagedCluster) -> None:
metric_annotations_allow_list=str(ksm_metric_annotations_allow_list)
))
mc.azure_monitor_profile.metrics.kube_state_metrics = kube_state_metrics

# Enable control plane metrics if requested.
if self.context.get_enable_control_plane_metrics():
mc.azure_monitor_profile.metrics.control_plane = (
self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=True)
)

Comment on lines +4711 to +4716
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.

Fixed in a7b923c — set_up_azure_monitor_profile now calls get_enable_control_plane_metrics() unconditionally so passing --enable-control-plane-metrics without the parent flag raises RequiredArgumentMissingError on create instead of being silently ignored when _setup_azure_monitor_metrics is skipped.

self.context.set_intermediate("azuremonitormetrics_addon_enabled", True, overwrite_exists=True)

def _setup_azure_monitor_app_monitoring(self, mc: ManagedCluster) -> None:
Expand Down Expand Up @@ -4741,6 +4833,11 @@ def set_up_azure_monitor_profile(self, mc: ManagedCluster) -> ManagedCluster:
"""
self._ensure_mc(mc)

# Trigger control-plane-metrics validation even if the parent metrics flag was
# not specified, so users get a clear error instead of silent ignore when they
# pass --enable-control-plane-metrics on its own.
self.context.get_enable_control_plane_metrics()

if self.context.get_enable_azure_monitor_metrics():
self._setup_azure_monitor_metrics(mc)

Expand Down Expand Up @@ -6908,6 +7005,30 @@ def update_azure_monitor_profile(self, mc: ManagedCluster) -> ManagedCluster:
if self.context.get_disable_azure_monitor_metrics():
self._disable_azure_monitor_metrics(mc)

# Handle enable / disable of control plane metrics independently of the parent metrics flag,
# so users can toggle control plane metrics on a cluster that already has metrics enabled.
if self.context.get_enable_control_plane_metrics():
if mc.azure_monitor_profile is None:
mc.azure_monitor_profile = self.models.ManagedClusterAzureMonitorProfile() # pylint: disable=no-member
if mc.azure_monitor_profile.metrics is None:
# Should not normally happen — validation requires metrics to be enabled — but guard
# against partially-populated profiles to avoid AttributeError.
mc.azure_monitor_profile.metrics = (
self.models.ManagedClusterAzureMonitorProfileMetrics(enabled=True) # pylint: disable=no-member
)
mc.azure_monitor_profile.metrics.control_plane = (
self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=True) # pylint: disable=no-member
)

if self.context.get_disable_control_plane_metrics():
if (
mc.azure_monitor_profile and
mc.azure_monitor_profile.metrics
):
mc.azure_monitor_profile.metrics.control_plane = (
self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=False) # pylint: disable=no-member
)
Comment on lines +7008 to +7030
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.

Fixed in 3f343fe — added 5 update-decorator tests covering: (1) enable-cp without parent flag raises RequiredArgumentMissingError, (2) enable-cp succeeds when AM metrics already on cluster, (3) enable-cp + disable-am-metrics raises MutuallyExclusiveArgumentError, (4) enable-cp + disable-cp together raises MutuallyExclusiveArgumentError, (5) disable-cp writes control_plane.enabled=False.


if self.context.get_enable_azure_monitor_app_monitoring():
if mc.azure_monitor_profile is None:
mc.azure_monitor_profile = self.models.ManagedClusterAzureMonitorProfile()
Expand Down
Loading
Loading