Back to Checks
azure

MySQL flexible server has high availability enabled

mysql_flexible_server_high_availability_enabled
Service: mysqlSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:microsoft.dbformysql/flexibleservers

Azure MySQL Flexible Server is evaluated for high availability mode. Zone-redundant or same-zone HA provisions a standby replica and provides automatic failover during planned and unplanned outages.

Risk

Without high availability, a server or zone failure causes downtime until manual recovery or redeployment. Applications experience extended unavailability and potential data loss for in-flight transactions during unplanned outages.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks mysql_flexible_server_high_availability_enabled

Recommendation

Enable high availability (zone-redundant where supported, otherwise same-zone) on production MySQL Flexible Servers so a standby replica provides automatic failover. High availability requires the General Purpose or Business Critical tier; pair it with geo-redundant backup and periodic failover testing for full resilience.

Remediation

CLI

az mysql flexible-server update --name <server_name> --resource-group <resource_group_name> --high-availability ZoneRedundant

Terraform

# Terraform: MySQL Flexible Server with zone-redundant high availability
resource "azurerm_mysql_flexible_server" "<example_resource_name>" {
  name                = "<example_resource_name>"
  resource_group_name = "<example_resource_name>"
  location            = "<region>"
  sku_name            = "GP_Standard_D2ds_v4"

  high_availability {
    mode = "ZoneRedundant" # CRITICAL: provisions a standby replica with automatic failover
  }
}

NativeIaC

// Bicep: MySQL Flexible Server with zone-redundant high availability
resource mysql 'Microsoft.DBforMySQL/flexibleServers@2023-12-30' = {
  name: '<example_resource_name>'
  location: '<region>'
  sku: {
    name: 'Standard_D2ds_v4'
    tier: 'GeneralPurpose'
  }
  properties: {
    highAvailability: {
      mode: 'ZoneRedundant' // CRITICAL: provisions a standby replica with automatic failover
    }
  }
}

Other

1In the Azure portal, open your Azure Database for MySQL flexible server
2Under Settings, select High availability
3Enable High availability and choose Zone redundant (or Same zone)
4Save (high availability requires the General Purpose or Business Critical tier)

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.mysql.mysql_client import mysql_client


class mysql_flexible_server_high_availability_enabled(Check):
    """
    Ensure Azure MySQL Flexible Servers have high availability enabled.

    This check evaluates whether each Azure MySQL Flexible Server is configured with high availability (zone-redundant or same-zone), providing automatic failover to a standby replica during outages.

    - PASS: The server has high availability enabled (high_availability_mode is set and not "Disabled").
    - FAIL: The server does not have high availability enabled.
    """

    def execute(self) -> Check_Report_Azure:
        findings = []
        for subscription_id, servers in mysql_client.flexible_servers.items():
            subscription_name = mysql_client.subscriptions.get(
                subscription_id, subscription_id
            )
            for server in servers.values():
                report = Check_Report_Azure(metadata=self.metadata(), resource=server)
                report.subscription = subscription_id
                if (
                    server.high_availability_mode is not None
                    and server.high_availability_mode != "Disabled"
                ):
                    report.status = "PASS"
                    report.status_extended = f"High availability is enabled for server {server.name} in subscription {subscription_name} ({subscription_id})."
                else:
                    report.status = "FAIL"
                    report.status_extended = f"High availability is disabled for server {server.name} in subscription {subscription_name} ({subscription_id})."
                findings.append(report)
        return findings