Microsoft’s documentation has a link to a QuickStart template that does this, but it doesn’t follow naming conventions for some reason. Here’s an ARM template to fix that.
Resources Created:
- NetworkWatcherRG resource group w/ Network Watcher
- Other Resource Groups Specified in Parameters
- App Service Plan
- App Service
- Private DNS Zone
- MySQL Flexible Server
- Azure Database for MySQL Flexible Server
- VNET including app and database subnets
You will still have to retool these JSON files, I’ve noted the properties that you will need to specify like <this>. There are other values that you may prefer to modify regardless. The naming conventions follow those specified in Microsoft’s documentation. This ARM template creates a vnet with a /16 scope and creates two /24 subnets. This usually defaults to 10.0.0.0/24 and 10.0.1.0/24 which may not suit everyone.
Once deployment is finished, you can navigate to the site.
- Website: www.website.azuresites.net
- Admin: www.website.azuresites.net/admin
- Flexible Server: www.website.azuresites.net/phpmyadmin
For the hobbyist, I like the default WordPress current year theme since it’s fast and generally uses good practices. I’ve made several websites from Dreamweaver, or pure HTML, CSS, and Java in high school and college but no point in re-inventing the wheel. If you NEED a bespoke theme don’t pay less than $1,000-2,000 unless you want a reskinned template. Regardless of what you choose, use dark mode and keep content centered.
You will 99% save money using a shared host, but it’s fun to make your own server. Keep in mind your website will be slow unless you set up CDN.
A website should be eye-catching, snappy, and full of useful content. Don’t let web developers bloat your page with spyware and crypto miners.
ARM Template
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"subscriptionId": {
"type": "string"
},
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"hostingPlanName": {
"type": "string"
},
"serverFarmResourceGroup": {
"type": "string"
},
"ftpsState": {
"type": "string"
},
"sku": {
"type": "string"
},
"skuCode": {
"type": "string"
},
"workerSize": {
"type": "string"
},
"workerSizeId": {
"type": "string"
},
"numberOfWorkers": {
"type": "string"
},
"kind": {
"type": "string"
},
"reserved": {
"type": "bool"
},
"alwaysOn": {
"type": "bool"
},
"linuxFxVersion": {
"type": "string"
},
"dockerRegistryUrl": {
"type": "string"
},
"storageSizeGB": {
"type": "int"
},
"storageIops": {
"type": "int"
},
"storageAutoGrow": {
"type": "string"
},
"storageAutoIoScaling": {
"type": "string"
},
"backupRetentionDays": {
"type": "int"
},
"geoRedundantBackup": {
"type": "string"
},
"charset": {
"type": "string"
},
"collation": {
"type": "string"
},
"vmName": {
"type": "string"
},
"serverEdition": {
"type": "string"
},
"vCores": {
"type": "int"
},
"serverName": {
"type": "string"
},
"serverUsername": {
"type": "string"
},
"serverPassword": {
"type": "securestring"
},
"databaseName": {
"type": "string"
},
"publicNetworkAccess": {
"type": "string"
},
"wordpressTitle": {
"type": "string"
},
"wordpressAdminEmail": {
"type": "string"
},
"wordpressUsername": {
"type": "string"
},
"wordpressPassword": {
"type": "securestring"
},
"wpLocaleCode": {
"type": "string"
},
"vnetName": {
"type": "string"
},
"subnetForApp": {
"type": "string"
},
"subnetForDb": {
"type": "string"
},
"privateDnsZoneNameForDb": {
"type": "string"
},
"vnetrg": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "[variables('appServicesApiVersion')]",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('location')]",
"tags": {
"AppProfile": "Wordpress"
},
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'))]",
"[concat('Microsoft.DBforMySQL/flexibleServers/', parameters('serverName'), '/databases/', parameters('databaseName'))]"
],
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "DOCKER_REGISTRY_SERVER_URL",
"value": "[parameters('dockerRegistryUrl')]"
},
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"value": "true"
},
{
"name": "DATABASE_HOST",
"value": "[concat(parameters('serverName'),'.mysql.database.azure.com')]"
},
{
"name": "DATABASE_NAME",
"value": "[parameters('databaseName')]"
},
{
"name": "DATABASE_USERNAME",
"value": "[parameters('serverUsername')]"
},
{
"name": "DATABASE_PASSWORD",
"value": "[parameters('serverPassword')]"
},
{
"name": "WORDPRESS_ADMIN_EMAIL",
"value": "[parameters('wordpressAdminEmail')]"
},
{
"name": "WORDPRESS_ADMIN_USER",
"value": "[parameters('wordpressUsername')]"
},
{
"name": "WORDPRESS_ADMIN_PASSWORD",
"value": "[parameters('wordpressPassword')]"
},
{
"name": "WORDPRESS_TITLE",
"value": "[parameters('wordpressTitle')]"
},
{
"name": "WEBSITES_CONTAINER_START_TIME_LIMIT",
"value": "1800"
},
{
"name": "WORDPRESS_LOCALE_CODE",
"value": "[parameters('wpLocaleCode')]"
},
{
"name": "SETUP_PHPMYADMIN",
"value": "true"
},
{
"name": "WORDPRESS_LOCAL_STORAGE_CACHE_ENABLED",
"value": "true"
}
],
"connectionStrings": [],
"ftpsState": "[parameters('ftpsState')]",
"linuxFxVersion": "[parameters('linuxFxVersion')]",
"vnetRouteAllEnabled": true
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"clientAffinityEnabled": false
}
},
{
"apiVersion": "[variables('appServicesApiVersion')]",
"name": "[parameters('hostingPlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('location')]",
"kind": "[parameters('kind')]",
"tags": {
"AppProfile": "Wordpress"
},
"properties": {
"name": "[parameters('hostingPlanName')]",
"workerSize": "[parameters('workerSize')]",
"workerSizeId": "[parameters('workerSizeId')]",
"numberOfWorkers": "[parameters('numberOfWorkers')]",
"reserved": "[parameters('reserved')]"
},
"sku": {
"Tier": "[parameters('sku')]",
"Name": "[parameters('skuCode')]"
},
"dependsOn": [
"[resourceId('Microsoft.DBforMySQL/flexibleServers', parameters('serverName'))]"
]
},
{
"apiVersion": "[variables('databaseApiVersion')]",
"location": "[parameters('location')]",
"name": "[parameters('serverName')]",
"type": "Microsoft.DBforMySQL/flexibleServers/",
"tags": {
"AppProfile": "Wordpress"
},
"properties": {
"version": "[variables('databaseVersion')]",
"administratorLogin": "[parameters('serverUsername')]",
"administratorLoginPassword": "[parameters('serverPassword')]",
"publicNetworkAccess": "[parameters('publicNetworkAccess')]",
"Storage": {
"StorageSizeGB": "[parameters('storageSizeGB')]",
"Iops": "[parameters('storageIops')]",
"Autogrow": "[parameters('storageAutoGrow')]",
"AutoIoScaling": "[parameters('storageAutoIoScaling')]"
},
"Backup": {
"backupRetentionDays": "[parameters('backupRetentionDays')]",
"geoRedundantBackup": "[parameters('geoRedundantBackup')]"
},
"Network": {
"PrivateDnsZoneResourceId": "[resourceId('Microsoft.Network/privateDnsZones', parameters('privateDnsZoneNameForDb'))]",
"DelegatedSubnetResourceId": "[resourceId(parameters('vnetrg'),'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetForDb'))]"
}
},
"sku": {
"name": "[parameters('vmName')]",
"tier": "[parameters('serverEdition')]",
"capacity": "[parameters('vCores')]"
},
"dependsOn": [
"[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', parameters('privateDnsZoneNameForDb'), format('{0}-vnetlink', parameters('privateDnsZoneNameForDb')))]",
"[resourceId(parameters('vnetrg'),'Microsoft.Resources/deployments', 'subnet_Resources')]"
]
},
{
"type": "Microsoft.DBforMySQL/flexibleServers/databases",
"name": "[format('{0}/{1}', parameters('serverName'), parameters('databaseName') )]",
"apiVersion": "[variables('databaseApiVersion')]",
"properties": {
"charset": "[parameters('charset')]",
"collation": "[parameters('collation')]"
},
"dependsOn": [
"[resourceId('Microsoft.DBforMySQL/flexibleServers', parameters('serverName'))]"
]
},
{
"type": "Microsoft.Resources/deployments",
"name": "subnet_Resources",
"apiVersion": "2020-06-01",
"dependsOn": [],
"resourceGroup": "rg-<appname>-prod-001",
"subscriptionId": "<subscriptionID>",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2021-03-01",
"name": "[format('{0}/{1}', parameters('vnetName'), parameters('subnetForApp'))]",
"properties": {
"addressPrefix": "<subnet1>/<cidr>",
"delegations": [
{
"name": "dlg-appService",
"properties": {
"serviceName": "Microsoft.Web/serverFarms"
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"apiVersion": "2021-03-01",
"name": "[format('{0}/{1}',parameters('vnetName'), parameters('subnetForDb'))]",
"properties": {
"addressPrefix": "<subnet2>/<cidr>",
"delegations": [
{
"name": "dlg-appService",
"properties": {
"serviceName": "Microsoft.DBforMySQL/flexibleServers"
}
}
]
},
"dependsOn": [
"[resourceId(parameters('vnetrg'),'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetForApp'))]"
]
}
]
}
}
},
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "[variables('privateDnsApiVersion')]",
"name": "[parameters('privateDnsZoneNameForDb')]",
"location": "global",
"tags": {
"AppProfile": "Wordpress"
},
"resources": [
{
"type": "virtualNetworkLinks",
"apiVersion": "[variables('privateDnsApiVersion')]",
"name": "[format('{0}-vnetlink', parameters('privateDnsZoneNameForDb'))]",
"location": "global",
"dependsOn": [
"[resourceId('Microsoft.Network/privateDnsZones', parameters('privateDnsZoneNameForDb'))]"
],
"properties": {
"virtualNetwork": {
"id": "[resourceId(parameters('vnetrg'),'Microsoft.Network/virtualNetworks/', parameters('vnetName'))]"
},
"registrationEnabled": false
}
}
],
"dependsOn": [
"[resourceId(parameters('vnetrg'),'Microsoft.Resources/deployments', 'subnet_Resources')]"
]
},
{
"apiVersion": "[variables('appServicesApiVersion')]",
"type": "Microsoft.Web/sites/networkConfig",
"name": "[format('{0}/{1}', parameters('name'), 'virtualNetwork')]",
"properties": {
"subnetResourceId": "[resourceId(parameters('vnetrg'),'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetForApp'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('name'))]",
"[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', parameters('privateDnsZoneNameForDb'), format('{0}-vnetlink', parameters('privateDnsZoneNameForDb')))]"
]
},
{
"type": "Microsoft.Web/sites/config",
"apiVersion": "[variables('appServicesApiVersion')]",
"name": "[concat(parameters('name'), '/web')]",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('name'))]",
"[resourceId('Microsoft.Web/sites/networkConfig', parameters('name'), 'virtualNetwork')]"
],
"properties": {
"alwaysOn": "[parameters('alwaysOn')]"
}
}
],
"variables": {
"appServicesApiVersion": "2021-03-01",
"databaseApiVersion": "2021-12-01-preview",
"databaseVersion": "8.0.21",
"vnetDeploymentApiVersion": "2020-07-01",
"privateDnsApiVersion": "2018-09-01",
"privateEndpointApiVersion": "2021-03-01",
"vnetAddress": "<vnetAddressSpace"
}
}
Template Parameters
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"subscriptionId": {
"value": "<subscriptionID>"
},
"name": {
"value": "azapp-<appname>"
},
"location": {
"value": "East US"
},
"hostingPlanName": {
"value": "asp-<appname>-prod-001"
},
"serverFarmResourceGroup": {
"value": "rg-<appname>-prod-001"
},
"ftpsState": {
"value": "FtpsOnly"
},
"sku": {
"value": "Basic"
},
"skuCode": {
"value": "B1"
},
"workerSize": {
"value": "3"
},
"workerSizeId": {
"value": "3"
},
"numberOfWorkers": {
"value": "1"
},
"kind": {
"value": "linux"
},
"reserved": {
"value": true
},
"alwaysOn": {
"value": true
},
"linuxFxVersion": {
"value": "DOCKER|mcr.microsoft.com/appsvc/wordpress-alpine-php:8.2"
},
"dockerRegistryUrl": {
"value": "https://mcr.microsoft.com"
},
"storageSizeGB": {
"value": 20
},
"storageIops": {
"value": 700
},
"storageAutoGrow": {
"value": "Enabled"
},
"storageAutoIoScaling": {
"value": "Enabled"
},
"backupRetentionDays": {
"value": 7
},
"geoRedundantBackup": {
"value": "Disabled"
},
"charset": {
"value": "utf8"
},
"collation": {
"value": "utf8_general_ci"
},
"vmName": {
"value": "Standard_B1ms"
},
"serverEdition": {
"value": "Burstable"
},
"vCores": {
"value": 1
},
"serverName": {
"value": "vm<appname>db01"
},
"serverUsername": {
"value": "<serverUsername>"
},
"serverPassword": {
"value": "<serverPassword>"
},
"databaseName": {
"value": "mysql-<appname>-prod"
},
"publicNetworkAccess": {
"value": "Disabled"
},
"wordpressTitle": {
"value": "<wordpressTitle>"
},
"wordpressAdminEmail": {
"value": "<wordpressAdminEmail>"
},
"wordpressUsername": {
"value": "<wordpressAdminUsername>"
},
"wordpressPassword": {
"value": "<wordpressPassword>"
},
"wpLocaleCode": {
"value": "en_US"
},
"vnetName": {
"value": "vnet-prod-eastus-001"
},
"subnetForApp": {
"value": "snet-app-eastus-001"
},
"subnetForDb": {
"value": "snet-db-eastus-001"
},
"privateDnsZoneNameForDb": {
"value": "azapp-<appname>-privatelink.mysql.database.azure.com"
},
"vnetrg": {
"value": "rg-<appname>-prod-001"
}
}
}