Back to Checks
azure

PostgreSQL flexible server has high availability enabled

postgresql_flexible_server_high_availability_enabled
Service: postgresqlSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:microsoft.dbforpostgresql/flexibleservers

Azure PostgreSQL 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. Critical databases 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 postgresql_flexible_server_high_availability_enabled

Recommendation

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

Remediation

CLI

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

Terraform

# Terraform: PostgreSQL Flexible Server with zone-redundant high availability
resource "azurerm_postgresql_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: PostgreSQL Flexible Server with zone-redundant high availability
resource postgresql 'Microsoft.DBforPostgreSQL/flexibleServers@2023-06-01-preview' = {
  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 PostgreSQL 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 Memory Optimized tier)

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.postgresql.postgresql_client import (
    postgresql_client,
)


class postgresql_flexible_server_high_availability_enabled(Check):
    """
    Ensure Azure PostgreSQL Flexible Servers have high availability enabled.

    This check evaluates whether each Azure PostgreSQL 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,
            flexible_servers,
        ) in postgresql_client.flexible_servers.items():
            subscription_name = postgresql_client.subscriptions.get(
                subscription, subscription
            )
            for server in flexible_servers:
                report = Check_Report_Azure(metadata=self.metadata(), resource=server)
                report.subscription = subscription
                if (
                    server.high_availability_mode is not None
                    and server.high_availability_mode != "Disabled"
                ):
                    report.status = "PASS"
                    report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription_name} ({subscription}) has high availability enabled."
                else:
                    report.status = "FAIL"
                    report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription_name} ({subscription}) does not have high availability enabled."
                findings.append(report)
        return findings