From 56dd772c901a07a1cb18b33ad0a12782326b3304 Mon Sep 17 00:00:00 2001
From: Timna Brown <24630902+brown9804@users.noreply.github.com>
Date: Tue, 13 May 2025 10:00:02 -0600
Subject: [PATCH 1/4] visual-guidance-enable-byRG
---
autoscaleMultiple-IOPS/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/autoscaleMultiple-IOPS/README.md b/autoscaleMultiple-IOPS/README.md
index 1e53fcf..a3b19ab 100644
--- a/autoscaleMultiple-IOPS/README.md
+++ b/autoscaleMultiple-IOPS/README.md
@@ -29,7 +29,7 @@ Last updated: 2025-05-13
## By Resource Group
-> Overall process:
(./scripts/enable_autoscale_iops_byRG.py)
+> Overall process:
>
> - Automatically retrieves your **Azure subscription ID** using the Azure CLI.
> - List all Resource Groups in current subscription ID.
@@ -41,7 +41,7 @@ Review [the script](./scripts/enable_autoscale_iops_byRG.py), and download it to
> Example: enabling Autoscale IOPS on two different servers, each hosted in same resource group and same subscription.
-
+https://github.com/user-attachments/assets/4c087afe-6fa1-40cb-bb2f-ef912edb974d
## Across a Subscription
From 7bd44488218dc069c429980104ca4f42c8e8414a Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Tue, 13 May 2025 16:00:25 +0000
Subject: [PATCH 2/4] Fix Markdown syntax issues
---
autoscaleMultiple-IOPS/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/autoscaleMultiple-IOPS/README.md b/autoscaleMultiple-IOPS/README.md
index a3b19ab..170d4c3 100644
--- a/autoscaleMultiple-IOPS/README.md
+++ b/autoscaleMultiple-IOPS/README.md
@@ -41,7 +41,7 @@ Review [the script](./scripts/enable_autoscale_iops_byRG.py), and download it to
> Example: enabling Autoscale IOPS on two different servers, each hosted in same resource group and same subscription.
-https://github.com/user-attachments/assets/4c087afe-6fa1-40cb-bb2f-ef912edb974d
+
## Across a Subscription
From edc8497221de227f13ff94b408296af604830be4 Mon Sep 17 00:00:00 2001
From: Timna Brown <24630902+brown9804@users.noreply.github.com>
Date: Tue, 13 May 2025 10:00:51 -0600
Subject: [PATCH 3/4] script
---
.../scripts/enable_autoscale_iops_byRG.py | 152 ++++++++++++++++++
1 file changed, 152 insertions(+)
create mode 100644 autoscaleMultiple-IOPS/scripts/enable_autoscale_iops_byRG.py
diff --git a/autoscaleMultiple-IOPS/scripts/enable_autoscale_iops_byRG.py b/autoscaleMultiple-IOPS/scripts/enable_autoscale_iops_byRG.py
new file mode 100644
index 0000000..bdbce1f
--- /dev/null
+++ b/autoscaleMultiple-IOPS/scripts/enable_autoscale_iops_byRG.py
@@ -0,0 +1,152 @@
+"""
+Azure MySQL Flexible Server Auto IOPS Enabler
+
+This script connects to Azure using the Azure CLI and Azure REST API to:
+1. Retrieve the current subscription ID.
+2. List all Resource Groups in current subscription ID.
+3. List all MySQL Flexible Servers in a specified resource group.
+4. Check if each server is eligible for Auto IOPS scaling (only GeneralPurpose or BusinessCritical tiers).
+5. Optionally enable Auto IOPS scaling if not already enabled.
+6. Print a summary of which servers were updated or skipped.
+
+You can use this script to:
+- Enable Auto IOPS scaling across all eligible servers in a resource group.
+- Target a specific server by name.
+"""
+
+import subprocess
+import requests
+import shutil
+from azure.identity import AzureCliCredential
+
+# Constants
+SUPPORTED_TIERS = {"GeneralPurpose", "BusinessCritical"}
+
+def mask_value(value, start=4, end=4):
+ return value[:start] + '*' * (len(value) - start - end) + value[-end:]
+
+def get_subscription_id():
+ az_path = shutil.which("az")
+ if az_path is None:
+ raise FileNotFoundError("Azure CLI (az) not found in system PATH.")
+ result = subprocess.check_output([az_path, "account", "show", "--query", "id", "-o", "tsv"], text=True)
+ return result.strip()
+
+def get_access_token():
+ credential = AzureCliCredential()
+ token = credential.get_token("https://management.azure.com/.default")
+ return token.token
+
+def list_resource_groups(subscription_id, access_token):
+ url = f"https://management.azure.com/subscriptions/{subscription_id}/resourcegroups?api-version=2024-06-01-preview"
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+ return response.json()
+
+def list_mysql_servers(subscription_id, resource_group, access_token):
+ url = (
+ f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/"
+ f"{resource_group}/providers/Microsoft.DBforMySQL/flexibleServers?api-version=2024-06-01-preview"
+ )
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+ return response.json()
+
+def get_server_config(subscription_id, resource_group, server_name, access_token):
+ url = (
+ f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/"
+ f"providers/Microsoft.DBforMySQL/flexibleServers/{server_name}?api-version=2024-06-01-preview"
+ )
+ headers = {"Authorization": f"Bearer {access_token}"}
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+ return response.json()
+
+def enable_auto_io_scaling_put(subscription_id, resource_group, server_name, access_token):
+ url = (
+ f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/"
+ f"providers/Microsoft.DBforMySQL/flexibleServers/{server_name}?api-version=2024-06-01-preview"
+ )
+ headers = {
+ "Authorization": f"Bearer {access_token}",
+ "Content-Type": "application/json"
+ }
+ payload = {
+ "properties": {
+ "storage": {
+ "autoIoScaling": "Enabled"
+ }
+ }
+ }
+ response = requests.patch(url, headers=headers, json=payload)
+ print(f"PATCH Response: {response.status_code} - {response.text}")
+ response.raise_for_status()
+ return response.json()
+
+def main():
+ try:
+ print("Script started")
+ subscription_id = get_subscription_id()
+ print(f"Using subscription: {mask_value(subscription_id)}")
+
+ access_token = get_access_token()
+ print(f"Access Token: {mask_value(access_token[:20])}...")
+
+ resource_groups = list_resource_groups(subscription_id, access_token)
+ print("Available Resource Groups:")
+ for rg in resource_groups.get("value", []):
+ print(f" - {rg['name']}")
+
+ resource_group = input("Enter the resource group name: ").strip()
+
+ servers = list_mysql_servers(subscription_id, resource_group, access_token)
+ print("Available MySQL Flexible Servers:")
+ for server in servers.get("value", []):
+ print(f" - {server['name']}")
+
+ target_server = input("Enter a specific server name (or press Enter to apply to all): ").strip()
+
+ eligible_servers = []
+ ineligible_servers = []
+
+ for server in servers.get("value", []):
+ server_name = server["name"]
+ if target_server and server_name.lower() != target_server.lower():
+ continue
+
+ config = get_server_config(subscription_id, resource_group, server_name, access_token)
+ tier = config["sku"]["tier"]
+ auto_io = config["properties"]["storage"].get("autoIoScaling", "Disabled")
+
+ if tier not in SUPPORTED_TIERS:
+ ineligible_servers.append((server_name, tier))
+ continue
+
+ if auto_io == "Enabled":
+ print(f"[SKIP] Auto IOPS already enabled for {server_name}")
+ continue
+
+ print(f"[UPDATE] Enabling Auto IOPS for {server_name} (Tier: {tier})...")
+ enable_auto_io_scaling_put(subscription_id, resource_group, server_name, access_token)
+ eligible_servers.append(server_name)
+
+ print("\nSummary:")
+ if eligible_servers:
+ print("Auto IOPS enabled for:")
+ for name in eligible_servers:
+ print(f" - {name}")
+ else:
+ print("No servers were updated.")
+
+ if ineligible_servers:
+ print("\nIneligible servers (unsupported tier):")
+ for name, tier in ineligible_servers:
+ print(f" - {name} (Tier: {tier})")
+
+ except Exception as e:
+ print(f"Error: {e}")
+
+if __name__ == "__main__":
+ main()
From 94d35c305341add5b68da81852f39888df5a7b67 Mon Sep 17 00:00:00 2001
From: Timna Brown <24630902+brown9804@users.noreply.github.com>
Date: Tue, 13 May 2025 10:03:30 -0600
Subject: [PATCH 4/4] comment
---
autoscaleMultiple-IOPS/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/autoscaleMultiple-IOPS/README.md b/autoscaleMultiple-IOPS/README.md
index 170d4c3..5aa5782 100644
--- a/autoscaleMultiple-IOPS/README.md
+++ b/autoscaleMultiple-IOPS/README.md
@@ -45,7 +45,7 @@ Review [the script](./scripts/enable_autoscale_iops_byRG.py), and download it to
## Across a Subscription
-> You can also enable autoscale IOPS across an entire subscription, it requires:
+> You can also enable autoscale IOPS across an entire subscription, overall process:
>
> - Listing all MySQL Flexible Servers in the subscription.
> - For each server, retrieving its resource group.