Running MySQL in Azure: Azure Database for MySQL
Azure Database for MySQL Flexible Server is Microsoft’s managed MySQL service. You get a real MySQL server — the same SQL syntax, drivers, and tools you already know — without managing the underlying OS, patching MySQL binaries, or setting up replication. This page walks through creating a server, connecting to it, and configuring it for production use.
What Flexible Server gives you
Azure Database for MySQL Flexible Server is the current generation of Azure’s managed MySQL service. Compared to the retired Single Server model, Flexible Server adds:
- Availability zone support — you can pin the server to a specific zone for predictable latency from zone-local VMs
- Same-zone high availability — a standby replica in the same zone for fast failover
- Zone-redundant high availability — standby in a different zone for higher resilience
- Configurable maintenance windows — you choose when patches and updates happen
- Burstable compute — smaller instance types that can burst CPU for short periods, good for dev/test
The MySQL version, connection strings, drivers, and SQL syntax are identical to a self-managed MySQL server. Migrating an existing MySQL application to Azure requires no code changes.
Creating a MySQL Flexible Server
# Create a MySQL Flexible Server with public access and a firewall rule
az mysql flexible-server create \
--resource-group my-storage-rg \
--name my-mysql-server-demo \
--location eastus \
--admin-user mysqladmin \
--admin-password "P@ssw0rd!MySQL123" \
--sku-name Standard_B1ms \
--tier Burstable \
--version 8.0 \
--storage-size 32 \
--public-access 0.0.0.0
# The --public-access 0.0.0.0 creates the server but only allows Azure services
# For dev access, add your own IP:
MY_IP=$(curl -s ifconfig.me)
az mysql flexible-server firewall-rule create \
--resource-group my-storage-rg \
--name my-mysql-server-demo \
--rule-name AllowMyIP \
--start-ip-address $MY_IP \
--end-ip-address $MY_IPThe Standard_B1ms SKU with Burstable tier is a small instance (1 vCore, 2 GB RAM) suitable for development. For production, use Standard_D or Standard_E tier with more vCores.
Available compute tiers:
- Burstable — low baseline CPU, can burst for short periods. Good for development and low-traffic apps.
- General Purpose — balanced compute and memory, suitable for most production workloads.
- Memory Optimized — high memory-to-vCore ratio, good for cache-heavy MySQL workloads.
Creating a server with VNet integration (production)
For production, create the server inside a VNet so it has no public endpoint:
# Create a VNet and subnet first
az network vnet create \
--resource-group my-storage-rg \
--name my-app-vnet \
--address-prefix 10.0.0.0/16
az network vnet subnet create \
--resource-group my-storage-rg \
--vnet-name my-app-vnet \
--name mysql-subnet \
--address-prefix 10.0.1.0/24
# Create the MySQL server with private VNet access
az mysql flexible-server create \
--resource-group my-storage-rg \
--name my-mysql-private \
--location eastus \
--admin-user mysqladmin \
--admin-password "P@ssw0rd!MySQL123" \
--sku-name Standard_D2ds_v4 \
--tier GeneralPurpose \
--version 8.0 \
--vnet my-app-vnet \
--subnet mysql-subnet \
--private-dns-zone my-mysql-private.private.mysql.database.azure.comWith VNet integration, the server gets a private IP address in the subnet. Only resources connected to the VNet (or peered networks) can reach it.
Connecting to the server
The connection hostname follows the pattern: <server-name>.mysql.database.azure.com.
# Connect with the standard MySQL client
mysql \
--host my-mysql-server-demo.mysql.database.azure.com \
--user mysqladmin \
--password \
--ssl-mode REQUIRED
# Or with all parameters inline (not recommended for interactive use — password appears in history)
mysql -h my-mysql-server-demo.mysql.database.azure.com \
-u mysqladmin -p"P@ssw0rd!MySQL123" \
--ssl-mode REQUIREDSSL is required by default. The MySQL client connects over TLS using Azure’s certificate. If your application’s MySQL client library requires an explicit SSL CA certificate, download the DigiCert Global Root G2 certificate from Microsoft’s documentation.
Basic operations after connecting
-- Create a database
CREATE DATABASE myappdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Create a dedicated application user (not using the admin account)
CREATE USER 'appuser'@'%' IDENTIFIED BY 'AppUserP@ss123';
GRANT SELECT, INSERT, UPDATE, DELETE ON myappdb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
-- Use the database
USE myappdb;
-- Create a table
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
sku VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(200) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
stock_quantity INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_sku (sku)
) ENGINE=InnoDB;
-- Insert test data
INSERT INTO products (sku, name, price, stock_quantity)
VALUES
('PROD-001', 'Widget A', 9.99, 100),
('PROD-002', 'Widget B', 14.99, 50),
('PROD-003', 'Gadget X', 49.99, 25);
-- Query with aggregation
SELECT
COUNT(*) AS total_products,
SUM(price * stock_quantity) AS total_inventory_value,
AVG(price) AS avg_price
FROM products;Server configuration parameters
Azure Database for MySQL exposes MySQL server variables that you can tune. Common ones to check:
# List all server parameters
az mysql flexible-server parameter list \
--resource-group my-storage-rg \
--server-name my-mysql-server-demo \
--output table
# Show a specific parameter
az mysql flexible-server parameter show \
--resource-group my-storage-rg \
--server-name my-mysql-server-demo \
--name max_connections
# Change a parameter (e.g., slow query log threshold)
az mysql flexible-server parameter set \
--resource-group my-storage-rg \
--server-name my-mysql-server-demo \
--name slow_query_log \
--value ON
az mysql flexible-server parameter set \
--resource-group my-storage-rg \
--server-name my-mysql-server-demo \
--name long_query_time \
--value 2Common mistakes
- Using the admin account in application connection strings. The admin account has superuser privileges. If your application’s connection string is compromised, an attacker gets full access to all databases on the server. Create a dedicated application user with only the permissions needed for that application.
- Not specifying the database character set on creation. MySQL defaults to latin1 in older versions or utf8mb3 in 8.0. Create databases with
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ciexplicitly. utf8mb4 supports the full Unicode range including emoji, while utf8mb3 (MySQL’s “utf8”) does not. - Choosing Burstable tier for production workloads. Burstable instances accumulate CPU credits and burst when available, but they can be throttled when credits run out. For sustained production traffic, use General Purpose or Memory Optimized. Burstable is for dev/test only.
- Forgetting that the server needs to be restarted after some parameter changes. Some MySQL server parameters require a server restart to take effect. Check the parameter’s
isDynamicConfigvalue — if false, a restart is needed. Plan maintenance windows for these changes.
Summary
- Azure Database for MySQL Flexible Server is the current-generation managed MySQL service, replacing the retired Single Server option.
- Use Burstable tier for development and General Purpose or Memory Optimized for production; VNet integration eliminates the public endpoint for production servers.
- SSL is required by default; always create a dedicated application user with minimal permissions rather than using the admin account.
- Server parameters are configurable via CLI; some require a restart while others take effect dynamically.
Frequently asked questions
What happened to Azure Database for MySQL Single Server?
Single Server was the original deployment model. Microsoft has retired it in favor of Flexible Server, which offers more control, better performance options, and additional features. If you have an existing Single Server deployment, Microsoft is migrating those to Flexible Server. All new MySQL deployments on Azure should use Flexible Server.
What MySQL versions does Azure Database for MySQL support?
Azure Database for MySQL Flexible Server supports MySQL 5.7 and MySQL 8.0. MySQL 5.7 reaches end of life in October 2023 (community support), so new applications should target MySQL 8.0.
Can I use Azure Database for MySQL with a VNet?
Yes. During creation you can deploy the server with private access (VNet integration), which means it has no public endpoint — only resources inside the VNet can connect. Alternatively, you can deploy with public access and restrict it with firewall rules. Private VNet access is recommended for production.