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: their compute tier, storage, high availability, and backup configuration. This guide focuses on three capabilities: production server deployment with HA, read replica creation, and point-in-time restore.

MySQL servers require an Azure resource group and region. Replicas and restores reference existing source servers by resource ID. The examples are intentionally small. Combine them with your own networking, encryption, and maintenance window configuration.

Create a server with high availability and backup configuration

Production deployments require zone-redundant high availability to survive datacenter failures and 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 sets the compute tier and VM size. The highAvailability block enables zone-redundant mode, placing a standby replica in a different availability zone. The backup block configures retention days and interval; geoRedundantBackup can replicate backups to a paired region. The storage block sets capacity, IOPS, and redundancy level.

Create a read replica for scaling read workloads

Applications with heavy read traffic deploy read replicas to distribute query load across multiple servers.

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 full resource ID. Replicas inherit the primary’s configuration but can be placed in different regions for geographic distribution.

Restore a server to a specific point in time

When data corruption occurs, point-in-time restore creates a new server from automated backups at a specific timestamp.

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 (ISO8601 format). The new server is independent; you can modify its SKU or configuration after creation. The source server must have backups covering the requested timestamp.

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 replica and restore scenarios). They focus on configuring the server rather than provisioning networking or encryption infrastructure.

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

  • Customer-managed encryption keys (dataEncryption)
  • VNet integration and private endpoints (network)
  • Maintenance window scheduling (maintenanceWindow)
  • Import from external MySQL sources (importSourceProperties)

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's the difference between the server creation modes?

You have three options:

  1. Default - Creates a new server with administratorLogin and administratorLoginPassword
  2. Replica - Creates a read replica using sourceServerResourceId
  3. PointInTimeRestore - Restores from backup using sourceServerResourceId and restorePointInTime
How do I create a read replica of my MySQL server?
Set createMode to Replica and provide sourceServerResourceId pointing to your primary server. Administrator credentials aren’t needed as they’re inherited from the source.
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”).
Do I need to specify administrator credentials when creating a replica or restore?
No, only Default mode requires administratorLogin and administratorLoginPassword. Replicas and restores inherit credentials from the source server.
Configuration & Immutability
What server properties can't I change after creation?
These properties are immutable: location, administratorLogin, availabilityZone, createMode, network, resourceGroupName, restorePointInTime, serverName, and sourceServerResourceId. Changing them requires recreating the server.
Can I change the administrator login name after creating the server?
No, administratorLogin is immutable. You can only change the password using administratorLoginPassword.
Can I move my server to a different availability zone?
No, availabilityZone is immutable after creation. Plan your zone placement carefully during initial setup.
High Availability & Disaster Recovery
What high availability options are available?
Configure highAvailability with mode set to ZoneRedundant and specify standbyAvailabilityZone for automatic failover to a different zone.
How do I configure automated backups?
Use the backup object to set backupIntervalHours (e.g., 24), backupRetentionDays (e.g., 7), and geoRedundantBackup (Enabled/Disabled).
Storage & Performance
What storage options can I configure?
The storage object lets you set storageSizeGB, iops, autoGrow (Enabled/Disabled), and storageRedundancy (LocalRedundancy/GeoRedundancy).
How do I choose the right SKU for my server?
Configure sku with name (e.g., “Standard_D2ds_v4”) and tier (e.g., GeneralPurpose). The example shows a GeneralPurpose tier with Standard_D2ds_v4.

Using a different cloud?

Explore database guides for other cloud providers: