MySQL Support
SQL Build Manager supports MySQL as a first-class database target alongside Microsoft SQL Server and PostgreSQL.
Select MySQL at runtime with --platform MySQL.
Quick Start
To run a build against a MySQL database, add --platform MySQL:
sbm build ^
--packagename "mypackage.sbm" ^
--server "mysql-server.mysql.database.azure.com" ^
--database "mydb" ^
--username "myuser" ^
--password "mypassword" ^
--platform MySQL
For threaded execution across multiple MySQL databases:
sbm threaded run ^
--packagename "mypackage.sbm" ^
--override "mysql-databasetargets.cfg" ^
--username "myuser" ^
--password "mypassword" ^
--platform MySQL
How It Works
When --platform MySQL is specified:
- Connections use MySqlConnector (
MySqlConnection). - Transactions use savepoint semantics compatible with MySQL execution.
- SQL syntax is adapted for MySQL execution and logging queries.
- Build logging uses a MySQL-native
sqlbuild_loggingtable (DATETIME(6),LONGTEXT,TINYINT(1),CHAR(36)). - Runtime wiring selects MySQL-specific implementations for:
IDbConnectionFactoryITransactionManagerIScriptSyntaxProviderISqlResourceProvider
Script Authoring Notes
When authoring scripts for MySQL targets, use MySQL-compatible syntax.
| SQL Server | MySQL |
|---|---|
GO batch separator |
Not required; terminate statements with ; |
[dbo].[TableName] |
`table_name` (or unquoted names) |
NVARCHAR(MAX) |
LONGTEXT |
DATETIME |
DATETIME(6) |
BIT |
TINYINT(1) |
UNIQUEIDENTIFIER |
CHAR(36) (or BINARY(16) if desired) |
GETDATE() |
NOW() / CURRENT_TIMESTAMP |
IDENTITY(1,1) |
AUTO_INCREMENT |
TOP(n) |
LIMIT n |
If your fleet includes multiple database engines, maintain separate
.sbmpackages with platform-appropriate SQL.
Supported Execution Models
MySQL is supported across local and remote execution models:
| Execution Model | Command | MySQL Support |
|---|---|---|
| Local build | sbm build |
✅ Supported |
| Threaded | sbm threaded run |
✅ Supported |
| Azure Batch | sbm batch run |
✅ Supported |
| Kubernetes | sbm k8s run |
✅ Supported |
| Container Apps | sbm containerapp run |
✅ Supported |
| ACI | sbm aci run |
✅ Supported |
Settings Files
--platform MySQL is preserved in saved settings files.
sbm batch savesettings ^
--settingsfile "mysql-settings.json" ^
--settingsfilekey "mykey" ^
--platform MySQL ^
--server "mysql-server.mysql.database.azure.com" ^
--username "myuser" ^
--password "mypassword"
For azd up environments, post-provision generates MySQL managed-identity settings in src\TestConfig\<envName> for the selected compute platforms:
settingsfile-aci-mysql-mi-only.jsonsettingsfile-batch-linux-mysql-mi-only.jsonsettingsfile-batch-linux-queue-mysql-mi-only.jsonsettingsfile-containerapp-mysql-mi-only.jsonsettingsfile-k8s-mysql-mi-only.json
Authentication
Username/Password
--authtype Password --username "myuser" --password "mypassword"
Local and local-container tests continue to use native username/password authentication. They do not require Entra ID, Azure tokens, or Azure connectivity. Explicit legacy Azure deployments can retain MYSQL_AUTH_MODE=Password, but the Azure MySQL test suites reject password settings.
Managed Identity (Azure MySQL)
Managed identity is the default Azure MySQL test mode (MYSQL_AUTH_MODE=ManagedIdentity). Azure Database for MySQL Flexible Server supports Entra authentication; database authorization must be provisioned separately.
--platform MySQL --authtype ManagedIdentity --clientid "<managed-identity-client-id>" --identityname "<managed-identity-name>"
The deploying Entra user is the MySQL Entra administrator. The server uses a dedicated id-{env}-mysql-directory identity for directory lookups, separate from both the private bootstrap identity and the id-{env}-worker identity used by database tests. Do not attach this directory identity to containers or grant its Graph permissions to workers. The operator needs Privileged Role Administrator (or Global Administrator) to grant the server identity User.Read.All, GroupMember.Read.All, and Application.Read.All, as described in Microsoft’s setup guide.
The launcher acquires a short-lived administrator token just before starting private bootstrap ACI and passes it as a secure environment variable, not an image layer or ordinary ARM environment value. Inside ACI, MySQL initialization runs first; mysql receives the token through temporary MYSQL_PWD, not a password argument. The parent clears the token before running other database initialization scripts. Bootstrap creates an Entra user for the runtime identity and grants privileges only on sbm_mysql_testN databases. It refuses to replace an existing native user or a principal mapped to another identity. Native server-administrator provisioning credentials remain available; they are not used by Azure tests.
ACI, Batch and Container Apps use their assigned managed identity. AKS uses its federated workload-identity token. Token-authenticated MySQL connections verify the server certificate and hostname.
TLS verification
Azure MySQL service endpoints require SslMode=VerifyFull for both native-password
and supported token authentication, including direct Azure-test connections. Public,
US Government, China and legacy Germany service suffixes are recognized, including
private-link names and an explicit port. A multi-host connection containing an Azure
endpoint uses the verified policy for the entire connection.
Use the canonical server FQDN with private DNS and a current OS/container CA trust
store. Custom aliases and IP addresses are not automatically classified as Azure and
may not match the certificate. Neither a private endpoint nor encryption alone proves
server identity. Verification failures are not retried with a weaker TLS mode.
The private bootstrap retains VERIFY_IDENTITY (MySQL) or --ssl-verify-server-cert
(MariaDB) with its trusted CA bundle.
Native local and local-container connections retain Preferred: TLS is opportunistic,
without mandatory certificate verification or local certificate provisioning. This
exception does not change the existing VerifyFull policy for token authentication.
Connection tests include real MySqlConnector protocol exchanges with temporary test certificates, covering trusted, wrong-host, untrusted, expired and plaintext cases. MySqlConnector 2.6.2 defers some native-auth certificate checks until the authentication response; these tests verify rejection before database commands. Its explicit loopback exception for cleartext-plugin credentials means local fixtures do not prove remote token-rejection behavior. Live Azure MI/private-DNS acceptance remains a separate check.
Migrating an existing Azure test environment
Identity-separation scope: the current R3 templates and runners target fresh disposable environments. The earlier authentication-only procedure below is not an RBAC migration: incremental Bicep does not remove old Contributor/AKS administrator assignments or stale identity attachments. Use a fresh environment and regenerate settings/images for the new worker/orchestrator identities. No automatic legacy-role revocation or migration tooling is provided.
Existing saved Password selections are not silently changed. Select the intended environment and set:
azd env set MYSQL_AUTH_MODE ManagedIdentity
Move stale Azure MySQL password settings (settingsfile-*-mysql-password.json) and mysql-pw.txt out of the selected src\TestConfig\<envName> directory (or explicit -path) before rerunning azd up; the target generator refuses to continue while these artifacts would still be copied into that environment’s test image. Other environment folders and legacy flat root files are not copied or used as a fallback. Do not change local/local-container credential files. Sign in to Azure CLI as the deploying Entra user, rerun azd up to update the administrator/grants and regenerate settings, and rebuild both runtime and Azure test images. Use scripts\tests\run_all_mysql_external_tests_in_aci.ps1 -envName <env> -buildImage when ready to run Azure tests. For local Azure test execution, pass -p:AzdEnvironment=<env> to dotnet test or set AZURE_ENV_NAME; see configuration selection.
Headless service-principal-only bootstrap is not supported by this workflow; it fails rather than falling back to a native password. After a token-expiry or directory-propagation failure, rerun postprovision as the same deploying user to obtain a fresh token.
Features Not Yet Available for MySQL
The following remain SQL Server-only:
- DACPAC operations (
create fromdacpacs,create fromdacpacdiff,--platinumdacpac,--targetdacpac,--forcecustomdacpac) - SMO-based object scripting
- Windows integrated authentication (
--authtype Windows) - SQL Server-specific script policies (for example,
WithNoLockPolicy,QualifiedNamesPolicy, T-SQL syntax checks)