Deploy Azure Database for MySQL Servers

The azure-native:dbformysql:Server resource, part of the Pulumi Azure Native provider, provisions Azure Database for MySQL flexible servers with compute, storage, and availability configuration. This guide focuses on three capabilities: high availability and backup configuration, read replica creation, and point-in-time restore.

MySQL servers require an Azure resource group and may reference source servers for replication or restore operations. The examples are intentionally small. Combine them with your own network configuration, encryption keys, and maintenance windows.

Create a server with high availability and backup configuration

Production deployments typically require zone-redundant high availability to survive datacenter failures, along with automated backups for disaster recovery.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const server = new azure_native.dbformysql.Server("server", {
    administratorLogin: "cloudsa",
    administratorLoginPassword: "your_password",
    availabilityZone: "1",
    backup: {
        backupIntervalHours: 24,
        backupRetentionDays: 7,
        geoRedundantBackup: azure_native.dbformysql.EnableStatusEnum.Disabled,
    },
    createMode: azure_native.dbformysql.CreateMode.Default,
    highAvailability: {
        mode: azure_native.dbformysql.HighAvailabilityMode.ZoneRedundant,
        standbyAvailabilityZone: "3",
    },
    location: "southeastasia",
    resourceGroupName: "testrg",
    serverName: "mysqltestserver",
    sku: {
        name: "Standard_D2ds_v4",
        tier: azure_native.dbformysql.ServerSkuTier.GeneralPurpose,
    },
    storage: {
        autoGrow: azure_native.dbformysql.EnableStatusEnum.Disabled,
        iops: 600,
        storageRedundancy: azure_native.dbformysql.StorageRedundancyEnum.LocalRedundancy,
        storageSizeGB: 100,
    },
    tags: {
        num: "1",
    },
    version: azure_native.dbformysql.ServerVersion.ServerVersion_5_7,
});
import pulumi
import pulumi_azure_native as azure_native

server = azure_native.dbformysql.Server("server",
    administrator_login="cloudsa",
    administrator_login_password="your_password",
    availability_zone="1",
    backup={
        "backup_interval_hours": 24,
        "backup_retention_days": 7,
        "geo_redundant_backup": azure_native.dbformysql.EnableStatusEnum.DISABLED,
    },
    create_mode=azure_native.dbformysql.CreateMode.DEFAULT,
    high_availability={
        "mode": azure_native.dbformysql.HighAvailabilityMode.ZONE_REDUNDANT,
        "standby_availability_zone": "3",
    },
    location="southeastasia",
    resource_group_name="testrg",
    server_name="mysqltestserver",
    sku={
        "name": "Standard_D2ds_v4",
        "tier": azure_native.dbformysql.ServerSkuTier.GENERAL_PURPOSE,
    },
    storage={
        "auto_grow": azure_native.dbformysql.EnableStatusEnum.DISABLED,
        "iops": 600,
        "storage_redundancy": azure_native.dbformysql.StorageRedundancyEnum.LOCAL_REDUNDANCY,
        "storage_size_gb": 100,
    },
    tags={
        "num": "1",
    },
    version=azure_native.dbformysql.ServerVersion.SERVER_VERSION_5_7)
package main

import (
	dbformysql "github.com/pulumi/pulumi-azure-native-sdk/dbformysql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbformysql.NewServer(ctx, "server", &dbformysql.ServerArgs{
			AdministratorLogin:         pulumi.String("cloudsa"),
			AdministratorLoginPassword: pulumi.String("your_password"),
			AvailabilityZone:           pulumi.String("1"),
			Backup: &dbformysql.BackupArgs{
				BackupIntervalHours: pulumi.Int(24),
				BackupRetentionDays: pulumi.Int(7),
				GeoRedundantBackup:  pulumi.String(dbformysql.EnableStatusEnumDisabled),
			},
			CreateMode: pulumi.String(dbformysql.CreateModeDefault),
			HighAvailability: &dbformysql.HighAvailabilityArgs{
				Mode:                    pulumi.String(dbformysql.HighAvailabilityModeZoneRedundant),
				StandbyAvailabilityZone: pulumi.String("3"),
			},
			Location:          pulumi.String("southeastasia"),
			ResourceGroupName: pulumi.String("testrg"),
			ServerName:        pulumi.String("mysqltestserver"),
			Sku: &dbformysql.MySQLServerSkuArgs{
				Name: pulumi.String("Standard_D2ds_v4"),
				Tier: pulumi.String(dbformysql.ServerSkuTierGeneralPurpose),
			},
			Storage: &dbformysql.StorageArgs{
				AutoGrow:          pulumi.String(dbformysql.EnableStatusEnumDisabled),
				Iops:              pulumi.Int(600),
				StorageRedundancy: pulumi.String(dbformysql.StorageRedundancyEnumLocalRedundancy),
				StorageSizeGB:     pulumi.Int(100),
			},
			Tags: pulumi.StringMap{
				"num": pulumi.String("1"),
			},
			Version: pulumi.String(dbformysql.ServerVersion_5_7),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var server = new AzureNative.DBforMySQL.Server("server", new()
    {
        AdministratorLogin = "cloudsa",
        AdministratorLoginPassword = "your_password",
        AvailabilityZone = "1",
        Backup = new AzureNative.DBforMySQL.Inputs.BackupArgs
        {
            BackupIntervalHours = 24,
            BackupRetentionDays = 7,
            GeoRedundantBackup = AzureNative.DBforMySQL.EnableStatusEnum.Disabled,
        },
        CreateMode = AzureNative.DBforMySQL.CreateMode.Default,
        HighAvailability = new AzureNative.DBforMySQL.Inputs.HighAvailabilityArgs
        {
            Mode = AzureNative.DBforMySQL.HighAvailabilityMode.ZoneRedundant,
            StandbyAvailabilityZone = "3",
        },
        Location = "southeastasia",
        ResourceGroupName = "testrg",
        ServerName = "mysqltestserver",
        Sku = new AzureNative.DBforMySQL.Inputs.MySQLServerSkuArgs
        {
            Name = "Standard_D2ds_v4",
            Tier = AzureNative.DBforMySQL.ServerSkuTier.GeneralPurpose,
        },
        Storage = new AzureNative.DBforMySQL.Inputs.StorageArgs
        {
            AutoGrow = AzureNative.DBforMySQL.EnableStatusEnum.Disabled,
            Iops = 600,
            StorageRedundancy = AzureNative.DBforMySQL.StorageRedundancyEnum.LocalRedundancy,
            StorageSizeGB = 100,
        },
        Tags = 
        {
            { "num", "1" },
        },
        Version = AzureNative.DBforMySQL.ServerVersion.ServerVersion_5_7,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbformysql.Server;
import com.pulumi.azurenative.dbformysql.ServerArgs;
import com.pulumi.azurenative.dbformysql.inputs.BackupArgs;
import com.pulumi.azurenative.dbformysql.inputs.HighAvailabilityArgs;
import com.pulumi.azurenative.dbformysql.inputs.MySQLServerSkuArgs;
import com.pulumi.azurenative.dbformysql.inputs.StorageArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var server = new Server("server", ServerArgs.builder()
            .administratorLogin("cloudsa")
            .administratorLoginPassword("your_password")
            .availabilityZone("1")
            .backup(BackupArgs.builder()
                .backupIntervalHours(24)
                .backupRetentionDays(7)
                .geoRedundantBackup("Disabled")
                .build())
            .createMode("Default")
            .highAvailability(HighAvailabilityArgs.builder()
                .mode("ZoneRedundant")
                .standbyAvailabilityZone("3")
                .build())
            .location("southeastasia")
            .resourceGroupName("testrg")
            .serverName("mysqltestserver")
            .sku(MySQLServerSkuArgs.builder()
                .name("Standard_D2ds_v4")
                .tier("GeneralPurpose")
                .build())
            .storage(StorageArgs.builder()
                .autoGrow("Disabled")
                .iops(600)
                .storageRedundancy("LocalRedundancy")
                .storageSizeGB(100)
                .build())
            .tags(Map.of("num", "1"))
            .version("5.7")
            .build());

    }
}
resources:
  server:
    type: azure-native:dbformysql:Server
    properties:
      administratorLogin: cloudsa
      administratorLoginPassword: your_password
      availabilityZone: '1'
      backup:
        backupIntervalHours: 24
        backupRetentionDays: 7
        geoRedundantBackup: Disabled
      createMode: Default
      highAvailability:
        mode: ZoneRedundant
        standbyAvailabilityZone: '3'
      location: southeastasia
      resourceGroupName: testrg
      serverName: mysqltestserver
      sku:
        name: Standard_D2ds_v4
        tier: GeneralPurpose
      storage:
        autoGrow: Disabled
        iops: 600
        storageRedundancy: LocalRedundancy
        storageSizeGB: 100
      tags:
        num: '1'
      version: '5.7'

The sku property defines compute capacity (Standard_D2ds_v4 provides 2 vCores). The highAvailability block enables zone-redundant deployment, placing a standby replica in a different availability zone. The backup block configures retention (7 days) and interval (24 hours), while storage sets capacity (100 GB) and IOPS (600). The administratorLogin and administratorLoginPassword establish initial credentials for database access.

Create a read replica for scaling read workloads

Applications with heavy read traffic often deploy read replicas to distribute query load across multiple servers while maintaining a single write endpoint.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const server = new azure_native.dbformysql.Server("server", {
    createMode: azure_native.dbformysql.CreateMode.Replica,
    location: "SoutheastAsia",
    resourceGroupName: "testgr",
    serverName: "replica-server",
    sourceServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server",
});
import pulumi
import pulumi_azure_native as azure_native

server = azure_native.dbformysql.Server("server",
    create_mode=azure_native.dbformysql.CreateMode.REPLICA,
    location="SoutheastAsia",
    resource_group_name="testgr",
    server_name="replica-server",
    source_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server")
package main

import (
	dbformysql "github.com/pulumi/pulumi-azure-native-sdk/dbformysql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbformysql.NewServer(ctx, "server", &dbformysql.ServerArgs{
			CreateMode:             pulumi.String(dbformysql.CreateModeReplica),
			Location:               pulumi.String("SoutheastAsia"),
			ResourceGroupName:      pulumi.String("testgr"),
			ServerName:             pulumi.String("replica-server"),
			SourceServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var server = new AzureNative.DBforMySQL.Server("server", new()
    {
        CreateMode = AzureNative.DBforMySQL.CreateMode.Replica,
        Location = "SoutheastAsia",
        ResourceGroupName = "testgr",
        ServerName = "replica-server",
        SourceServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbformysql.Server;
import com.pulumi.azurenative.dbformysql.ServerArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var server = new Server("server", ServerArgs.builder()
            .createMode("Replica")
            .location("SoutheastAsia")
            .resourceGroupName("testgr")
            .serverName("replica-server")
            .sourceServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server")
            .build());

    }
}
resources:
  server:
    type: azure-native:dbformysql:Server
    properties:
      createMode: Replica
      location: SoutheastAsia
      resourceGroupName: testgr
      serverName: replica-server
      sourceServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/testgr/providers/Microsoft.DBforMySQL/flexibleServers/source-server

The createMode property set to Replica tells Azure to create a read-only copy. The sourceServerResourceId points to the primary server by its full Azure resource ID. Replicas inherit configuration from the source server but can be placed in different regions for geographic distribution. This extends the basic server deployment by adding read scaling capacity.

Restore a server from a point in time backup

When data corruption or accidental deletion occurs, point-in-time restore creates a new server from automated backups without affecting the original server.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const server = new azure_native.dbformysql.Server("server", {
    createMode: azure_native.dbformysql.CreateMode.PointInTimeRestore,
    location: "SoutheastAsia",
    resourceGroupName: "TargetResourceGroup",
    restorePointInTime: "2021-06-24T00:00:37.467Z",
    serverName: "targetserver",
    sku: {
        name: "Standard_D14_v2",
        tier: azure_native.dbformysql.ServerSkuTier.GeneralPurpose,
    },
    sourceServerResourceId: "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver",
    tags: {
        num: "1",
    },
});
import pulumi
import pulumi_azure_native as azure_native

server = azure_native.dbformysql.Server("server",
    create_mode=azure_native.dbformysql.CreateMode.POINT_IN_TIME_RESTORE,
    location="SoutheastAsia",
    resource_group_name="TargetResourceGroup",
    restore_point_in_time="2021-06-24T00:00:37.467Z",
    server_name="targetserver",
    sku={
        "name": "Standard_D14_v2",
        "tier": azure_native.dbformysql.ServerSkuTier.GENERAL_PURPOSE,
    },
    source_server_resource_id="/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver",
    tags={
        "num": "1",
    })
package main

import (
	dbformysql "github.com/pulumi/pulumi-azure-native-sdk/dbformysql/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := dbformysql.NewServer(ctx, "server", &dbformysql.ServerArgs{
			CreateMode:         pulumi.String(dbformysql.CreateModePointInTimeRestore),
			Location:           pulumi.String("SoutheastAsia"),
			ResourceGroupName:  pulumi.String("TargetResourceGroup"),
			RestorePointInTime: pulumi.String("2021-06-24T00:00:37.467Z"),
			ServerName:         pulumi.String("targetserver"),
			Sku: &dbformysql.MySQLServerSkuArgs{
				Name: pulumi.String("Standard_D14_v2"),
				Tier: pulumi.String(dbformysql.ServerSkuTierGeneralPurpose),
			},
			SourceServerResourceId: pulumi.String("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver"),
			Tags: pulumi.StringMap{
				"num": pulumi.String("1"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var server = new AzureNative.DBforMySQL.Server("server", new()
    {
        CreateMode = AzureNative.DBforMySQL.CreateMode.PointInTimeRestore,
        Location = "SoutheastAsia",
        ResourceGroupName = "TargetResourceGroup",
        RestorePointInTime = "2021-06-24T00:00:37.467Z",
        ServerName = "targetserver",
        Sku = new AzureNative.DBforMySQL.Inputs.MySQLServerSkuArgs
        {
            Name = "Standard_D14_v2",
            Tier = AzureNative.DBforMySQL.ServerSkuTier.GeneralPurpose,
        },
        SourceServerResourceId = "/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver",
        Tags = 
        {
            { "num", "1" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.dbformysql.Server;
import com.pulumi.azurenative.dbformysql.ServerArgs;
import com.pulumi.azurenative.dbformysql.inputs.MySQLServerSkuArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var server = new Server("server", ServerArgs.builder()
            .createMode("PointInTimeRestore")
            .location("SoutheastAsia")
            .resourceGroupName("TargetResourceGroup")
            .restorePointInTime("2021-06-24T00:00:37.467Z")
            .serverName("targetserver")
            .sku(MySQLServerSkuArgs.builder()
                .name("Standard_D14_v2")
                .tier("GeneralPurpose")
                .build())
            .sourceServerResourceId("/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver")
            .tags(Map.of("num", "1"))
            .build());

    }
}
resources:
  server:
    type: azure-native:dbformysql:Server
    properties:
      createMode: PointInTimeRestore
      location: SoutheastAsia
      resourceGroupName: TargetResourceGroup
      restorePointInTime: 2021-06-24T00:00:37.467Z
      serverName: targetserver
      sku:
        name: Standard_D14_v2
        tier: GeneralPurpose
      sourceServerResourceId: /subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/SourceResourceGroup/providers/Microsoft.DBforMySQL/flexibleServers/sourceserver
      tags:
        num: '1'

The createMode property set to PointInTimeRestore initiates recovery. The restorePointInTime specifies the exact timestamp to restore from (must fall within the backup retention window). The sku can differ from the source server, allowing you to scale up or down during recovery. This creates a new independent server; the original remains unchanged.

Beyond these examples

These snippets focus on specific server-level features: server creation with HA and backup configuration, read replica deployment, and point-in-time restore. They’re intentionally minimal rather than full database deployments.

The examples may reference pre-existing infrastructure such as Azure resource groups and source servers for replication and restore operations. They focus on configuring the server rather than provisioning everything around it.

To keep things focused, common server patterns are omitted, including:

  • Network configuration (VNet integration, private endpoints)
  • Customer-managed encryption keys (dataEncryption)
  • Maintenance windows and update schedules
  • Import from external MySQL sources

These omissions are intentional: the goal is to illustrate how each server feature is wired, not provide drop-in database modules. See the Azure Database for MySQL Server resource reference for all available configuration options.

Let's deploy Azure Database for MySQL Servers

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Server Creation & Modes
What are the different ways to create a MySQL server?

You can create a server in three modes using createMode:

  1. Default - Create a new server with full configuration
  2. Replica - Create a read replica from an existing server
  3. PointInTimeRestore - Restore from a backup at a specific timestamp
How do I create a read replica?
Set createMode to Replica and provide sourceServerResourceId pointing to the primary server’s resource ID.
How do I restore a server from a point-in-time backup?
Set createMode to PointInTimeRestore, provide sourceServerResourceId and restorePointInTime in ISO8601 format (e.g., “2021-06-24T00:00:37.467Z”).
When do I need to specify administrator credentials?
administratorLogin and administratorLoginPassword are required when creating a new server (createMode is Default). The login name is immutable after creation.
Configuration & Immutability
What properties can't be changed after creating a server?
These properties are immutable: location, administratorLogin, availabilityZone, createMode, network, sourceServerResourceId, restorePointInTime, serverName, and resourceGroupName. Changes require recreating the server.
High Availability & Disaster Recovery
How do I enable zone-redundant high availability?
Configure highAvailability with mode set to ZoneRedundant and specify standbyAvailabilityZone (e.g., “3” if primary is in zone “1”).
What backup options can I configure?

The backup object supports:

  • backupIntervalHours - Frequency of backups (e.g., 24)
  • backupRetentionDays - Retention period (e.g., 7)
  • geoRedundantBackup - Enable/disable geo-redundancy (Disabled or Enabled)
Storage & Performance
How do I configure storage for my server?

Use the storage object to set:

  • storageSizeGB - Storage capacity (e.g., 100)
  • iops - Provisioned IOPS (e.g., 600)
  • autoGrow - Enable/disable auto-growth (Disabled or Enabled)
  • storageRedundancy - Redundancy type (e.g., LocalRedundancy)
What SKU options are available?
Configure sku with name (e.g., Standard_D2ds_v4) and tier (e.g., GeneralPurpose). The example shows a General Purpose tier with a D-series SKU.
Which MySQL versions are supported?
Set the version property to specify the MySQL version. The example shows version 5.7.

Using a different cloud?

Explore database guides for other cloud providers: