This directory contains the Bicep template and a deployment script for provisioning the sample's Azure resources. For details about the sample application, see Azure Web App with Azure Database for MySQL flexible server.
- LocalStack for Azure
- Visual Studio Code + Bicep extension
- Docker
- Azure CLI + lstk CLI
- Python 3.12+
- MySQL client (
mysql) jq
brew install localstack/tap/lstk # or: npm install -g @localstack/lstkThe deploy.sh script creates the resource group while the Bicep modules create:
- Azure Virtual Network with two subnets:
- app-subnet: delegated to
Microsoft.Web/serverFarmsfor the Web App's regional VNet integration. - pe-subnet: hosts the Private Endpoint to the MySQL flexible server.
- app-subnet: delegated to
- Azure Private DNS Zone
privatelink.mysql.database.azure.com, linked to the VNet. - Azure Private Endpoint (group
mysqlServer). - Azure NAT Gateway.
- Network Security Groups: one per subnet.
- Azure Log Analytics Workspace.
- Azure Database for MySQL flexible server: public-access mode, Burstable
Standard_B1ms, version 8.0.21, 32 GiB, HA disabled. A permissive firewall rule (0.0.0.0–255.255.255.255) lets the deploy machine reach the server for the post-create mysql bootstrap. - MySQL database
plannerdb(utf8mb4 /utf8mb4_unicode_ci). - Azure App Service Plan.
- Azure Web App with regional VNet integration into app-subnet. The Bicep template sets
MYSQL_HOST,MYSQL_PORT, andMYSQL_DATABASEon the Web App but does not setMYSQL_USERorMYSQL_PASSWORD— those are written bydeploy.shafter the mysql client creates the application user.
Update main.bicepparam before deploying. The defaults are:
using 'main.bicep'
param prefix = 'local'
param suffix = 'test'
param runtimeName = 'python'
param runtimeVersion = '3.13'
param databaseName = 'plannerdb'
param username = 'paolo'
param mysqlAdminLogin = 'myadmin'
param mysqlAdminPassword = readEnvironmentVariable('MYSQL_ADMIN_PASSWORD', '')
param mysqlVersion = '8.0.21'
param mysqlSkuTier = 'Burstable'
param mysqlSkuName = 'Standard_B1ms'
param mysqlStorageSizeGB = 32
param mysqlBackupRetentionDays = 7mysqlAdminPassword is read from the MYSQL_ADMIN_PASSWORD env var. deploy.sh sets a default (P@ssw0rd1234!) if not provided; override for non-dev deployments.
# default values
bash deploy.sh
# override admin and app-user secrets
MYSQL_ADMIN_PASSWORD='<your-admin-password>' \
MYSQL_APP_PASSWORD='<your-app-password>' \
bash deploy.shThe script will:
- Ensure the resource group exists.
- Validate
main.bicep. - Deploy the template, passing
mysqlAdminPassword. - Use the
mysqlclient (connected via the public endpoint + firewall rule) to create thetestuseruser, theactivitiestable, and the demo rows. - Set the Web App's
MYSQL_USER/MYSQL_PASSWORDtotestuser/<app-password>— the server admin login is never written to the Web App. - Zip the application source under
../srcand deploy it.
MYSQL_PWD='TestP@ssw0rd123' mysql -h <fqdn> -P <port> -u testuser plannerdb \
-e "SELECT id, username, activity, created_at FROM activities;"<port> is 3306 in real Azure, or the port suffix of the server's FQDN in LocalStack:
az mysql flexible-server show \
--resource-group local-rg --name local-mysqlflex-test \
--query fullyQualifiedDomainName --output tsv