Learn how to quickly deploy the latest Azure offer ‘WordPress on Azure App Service’ using Infrastructure-as-Code.
WordPress on Azure App Service, which was running on Public Preview since 15 February 2022, has been made Generally Available on 8 August 2022.
The purpose of this article is to help you perform a successful deployment of WordPress on Azure App Service in your environment using Infrastructure-as-Code with Azure Bicep.
Azure Bicep is a domain-specific language (DSL) that uses a declarative syntax to deploy Azure resources.
Major changes of WordPress on Azure App Service
- Performance
- Linux as the default option
- CDN — you can configure the Azure CDN integration
- Blob storage — you can opt to use Azure Blob Storage while creating a new WordPress on Azure App Service instance. It serves static content directly to the browser, reducing the load on your web server.
- Revised Hosting Plans — you have multiple hosting options for the WebApp Server(from vCores, 1.75 GB RAM, 10 GB Storage up to 2 vCores, 8 GB RAM, 250 GB Storage) and the Database server (from 1 vCores, 2 GiB RAM, 32 GiB storage, 400 IOPS up to vCores, 16 GiB RAM, 256 GiB storage, 1100 IOPS)
- Easy WordPress configuration — you can now choose the language of the WordPress website with other easy configuration options available.
- MySQL Flexible Servers — by using MySQL Flexible servers you have greater control over the database.
- phpMyAdmin — phpMyAdmin has been added to WordPress on Azure App Service. Access phpMyAdmin by visiting
https://Your-Site-URL/phpMyAdmin
Prerequisites
- An Active Azure account: You can create an account for free.
- Azure Bicep is installed on your local machine.
- Azure PowerShell. See: Install Azure PowerShell.
- A resource group in your Azure subscription
Let’s get started!
1. Solution Overview
We will author a Bicep template that creates a WordPress on Azure App Service.
The solution will include the following files:
- 📄 main.bicep: This is the Bicep template
- 📄 azuredeploy.parameters.json: This parameter file contains the values to use for deploying your Bicep template.
2. Azure Bicep Template — parameters
Create a new file in your working directory and name it ‘main.bicep’. We will define the following parameters:
param subscriptionId string
param name string
param location string
param hostingPlanName string
param serverFarmResourceGroup string
param sku string
param skuCode string
param workerSize string
param workerSizeId string
param numberOfWorkers string
param kind string
param reserved bool
param alwaysOn bool
param linuxFxVersion string
param dockerRegistryUrl string
param storageSizeGB int
param storageIops int
param storageAutoGrow string
param backupRetentionDays int
param geoRedundantBackup string
param charset string
param collation string
param vmName string
param serverEdition string
param vCores int
param serverName string
param serverUsername string@secure()
param serverPassword string
param databaseName string
param publicNetworkAccess string
param wordpressTitle string
param wordpressAdminEmail string
param wordpressUsername string@secure()
param wordpressPassword string
param wpLocaleCode string
param cdnProfileName string
param cdnEndpointName string
param cdnType string
param cdnEndpointProperties object
param vnetName string
param subnetForApp string
param subnetForDb string
param privateDnsZoneNameForDb string
3. Azure Bicep Template — variables
We will define the following variables:
var databaseVersion = '5.7'
var vnetAddress = '10.0.0.0/16'
var subnetAddressForApp = '10.0.0.0/24'
var subnetAddressForDb = '10.0.1.0/24'
4. Azure Bicep Template — resources
We will define the following resources:
resource name_resource 'Microsoft.Web/sites@2021-03-01' = {
name: name
location: location
tags: null
properties: {
name: name
siteConfig: {
appSettings: [
{
name: 'DOCKER_REGISTRY_SERVER_URL'
value: dockerRegistryUrl
}
{
name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE'
value: 'true'
}
{
name: 'DATABASE_HOST'
value: '${serverName}.mysql.database.azure.com'
}
{
name: 'DATABASE_NAME'
value: databaseName
}
{
name: 'DATABASE_USERNAME'
value: serverUsername
}
{
name: 'DATABASE_PASSWORD'
value: serverPassword
}
{
name: 'WORDPRESS_ADMIN_EMAIL'
value: wordpressAdminEmail
}
{
name: 'WORDPRESS_ADMIN_USER'
value: wordpressUsername
}
{
name: 'WORDPRESS_ADMIN_PASSWORD'
value: wordpressPassword
}
{
name: 'WORDPRESS_TITLE'
value: wordpressTitle
}
{
name: 'WEBSITES_CONTAINER_START_TIME_LIMIT'
value: '900'
}
{
name: 'WORDPRESS_LOCALE_CODE'
value: wpLocaleCode
}
{
name: 'SETUP_PHPMYADMIN'
value: 'true'
}
{
name: 'CDN_ENABLED'
value: 'true'
}
{
name: 'CDN_ENDPOINT'
value: '${cdnEndpointName}.azureedge.net'
}
]
connectionStrings: []
linuxFxVersion: linuxFxVersion
vnetRouteAllEnabled: true
}
serverFarmId: '/subscriptions/${subscriptionId}/resourcegroups/${serverFarmResourceGroup}/providers/Microsoft.Web/serverfarms/${hostingPlanName}'
clientAffinityEnabled: false
}
dependsOn: [
hostingPlanName_resource
serverName_resource
serverName_databaseName
]
}resource hostingPlanName_resource 'Microsoft.Web/serverfarms@2021-03-01' = {
name: hostingPlanName
location: location
kind: kind
tags: null
properties: {
name: hostingPlanName
workerSize: workerSize
workerSizeId: workerSizeId
numberOfWorkers: numberOfWorkers
reserved: reserved
}
sku: {
Tier: sku
Name: skuCode
}
dependsOn: [
serverName_resource
]
}resource serverName_resource 'Microsoft.DBforMySQL/flexibleServers@2021-05-01' = {
location: location
name: serverName
tags: {
AppProfile: 'Wordpress'
}
properties: {
version: databaseVersion
administratorLogin: serverUsername
administratorLoginPassword: serverPassword
publicNetworkAccess: publicNetworkAccess
Storage: {
StorageSizeGB: storageSizeGB
Iops: storageIops
Autogrow: storageAutoGrow
}
Backup: {
backupRetentionDays: backupRetentionDays
geoRedundantBackup: geoRedundantBackup
}
Network: {
PrivateDnsZoneResourceId: privateDnsZoneNameForDb_resource.id
DelegatedSubnetResourceId: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, subnetForDb)
}
}
sku: {
name: vmName
tier: serverEdition
capacity: vCores
}
dependsOn: [
privateDnsZoneNameForDb_privateDnsZoneNameForDb_vnetlink
]
}resource serverName_databaseName 'Microsoft.DBforMySQL/flexibleServers/databases@2021-05-01' = {
name: '${serverName}/${databaseName}'
properties: {
charset: charset
collation: collation
}
dependsOn: [
serverName_resource
]
}resource vnetName_resource 'Microsoft.Network/virtualNetworks@2020-07-01' = {
location: location
name: vnetName
properties: {
addressSpace: {
addressPrefixes: [
vnetAddress
]
}
subnets: [
{
name: subnetForApp
properties: {
addressPrefix: subnetAddressForApp
delegations: [
{
name: 'dlg-appService'
properties: {
serviceName: 'Microsoft.Web/serverFarms'
}
}
]
}
}
{
name: subnetForDb
properties: {
addressPrefix: subnetAddressForDb
delegations: [
{
name: 'dlg-database'
properties: {
serviceName: 'Microsoft.DBforMySQL/flexibleServers'
}
}
]
}
}
]
}
dependsOn: []
}resource privateDnsZoneNameForDb_resource 'Microsoft.Network/privateDnsZones@2018-09-01' = {
name: privateDnsZoneNameForDb
location: 'global'
dependsOn: []
}resource privateDnsZoneNameForDb_privateDnsZoneNameForDb_vnetlink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2018-09-01' = {
name: '${privateDnsZoneNameForDb}/${privateDnsZoneNameForDb}-vnetlink'
location: 'global'
properties: {
virtualNetwork: {
id: vnetName_resource.id
}
registrationEnabled: true
}
dependsOn: [
privateDnsZoneNameForDb_resource]
}resource name_virtualNetwork 'Microsoft.Web/sites/networkConfig@2021-03-01' = {
name: '${name}/virtualNetwork'
properties: {
subnetResourceId: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, subnetForApp)
}
dependsOn: [
name_resource
privateDnsZoneNameForDb_privateDnsZoneNameForDb_vnetlink
]
}resource name_web 'Microsoft.Web/sites/config@2021-03-01' = {
name: '${name}/web'
properties: {
alwaysOn: alwaysOn
}
dependsOn: [
name_resource
name_virtualNetwork
]
}resource cdnProfileName_resource 'Microsoft.Cdn/profiles@2020-04-15' = {
name: cdnProfileName
location: 'Global'
sku: {
name: cdnType
}
tags: {
AppProfile: 'Wordpress'
}
properties: {
}
dependsOn: [
serverName_resource
]
}resource cdnProfileName_cdnEndPointName 'Microsoft.Cdn/profiles/endpoints@2020-04-15' = {
name: '${cdnProfileName}/${cdnEndpointName}'
location: 'Global'
properties: cdnEndpointProperties
dependsOn: [
cdnProfileName_resource
name_resource
]
}
5. Parameters file
Create a new file named ‘azuredeploy.parameters.json’. The code below shows the definition of the parameters file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"subscriptionId": {
"value": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
},
"name": {
"value": "azinsider"
},
"location": {
"value": "eastus"
},
"hostingPlanName": {
"value": "ASP-azinsidrgroup-a6b8"
},
"serverFarmResourceGroup": {
"value": "azinsider_demo"
},
"sku": {
"value": "PremiumV2"
},
"skuCode": {
"value": "P1v2"
},
"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:latest"
},
"dockerRegistryUrl": {
"value": "https://mcr.microsoft.com"
},
"storageSizeGB": {
"value": 128
},
"storageIops": {
"value": 700
},
"storageAutoGrow": {
"value": "Enabled"
},
"backupRetentionDays": {
"value": 7
},
"geoRedundantBackup": {
"value": "Disabled"
},
"vmName": {
"value": "Standard_D2ds_v4"
},
"serverEdition": {
"value": "GeneralPurpose"
},
"vCores": {
"value": 2
},
"charset": {
"value": "utf8"
},
"collation": {
"value": "utf8_general_ci"
},
"serverName": {
"value": "azinsidr-f11bb8d5f4db45a685747f3dfa46d024-dbserver"
},
"serverUsername": {
"value": "ejkvvgbqlo"
},
"serverPassword": {
"value": "YourServerPassword"
},
"databaseName": {
"value": "azinsidr_f11bb8d5f4db45a685747f3dfa46d024_database"
},
"publicNetworkAccess": {
"value": "Disabled"
},
"wordpressTitle": {
"value": "WordPress On Azure"
},
"wordpressAdminEmail": {
"value": "Your-wordpress-admin-email"
},
"wordpressUsername": {
"value": "your-wordpress-username"
},
"wordpressPassword": {
"value": "YourWordPressPassword"
},
"wpLocaleCode": {
"value": "en_US"
},
"cdnProfileName": {
"value": "azinsidr-f72ddf40c97ef984e5ed-cdnprofile"
},
"cdnEndpointName": {
"value": "azinsidr-f72ddf40c97ef984e5ed-endpoint"
},
"cdnType": {
"value": "Standard_Microsoft"
},
"cdnEndpointProperties": {
"value": {
"isHttpAllowed": true,
"isHttpsAllowed": true,
"originHostHeader": "azinsidr.azurewebsites.net",
"origins": [
{
"name": "azinsidr-azurewebsites-net",
"properties": {
"hostName": "azinsidr.azurewebsites.net",
"httpPort": 80,
"httpsPort": 443,
"originHostHeader": "azinsidr.azurewebsites.net",
"priority": 1,
"weight": 1000,
"enabled": true
}
}
],
"isCompressionEnabled": true,
"contentTypesToCompress": [
"application/eot",
"application/font",
"application/font-sfnt",
"application/javascript",
"application/json",
"application/opentype",
"application/otf",
"application/pkcs7-mime",
"application/truetype",
"application/ttf",
"application/vnd.ms-fontobject",
"application/xhtml+xml",
"application/xml",
"application/xml+rss",
"application/x-font-opentype",
"application/x-font-truetype",
"application/x-font-ttf",
"application/x-httpd-cgi",
"application/x-javascript",
"application/x-mpegurl",
"application/x-opentype",
"application/x-otf",
"application/x-perl",
"application/x-ttf",
"font/eot",
"font/ttf",
"font/otf",
"font/opentype",
"image/svg+xml",
"text/css",
"text/csv",
"text/html",
"text/javascript",
"text/js",
"text/plain",
"text/richtext",
"text/tab-separated-values",
"text/xml",
"text/x-script",
"text/x-component",
"text/x-java-source"
]
}
},
"vnetName": {
"value": "azinsidr-436c376a86-vnet"
},
"subnetForApp": {
"value": "azinsidr-436c376a86-appsubnet"
},
"subnetForDb": {
"value": "azinsidr-436c376a86-dbsubnet"
},
"privateDnsZoneNameForDb": {
"value": "azinsidr-436c376a86-privatelink.mysql.database.azure.com"
}
}
}
6. Azure Bicep Template — Deployment
We will use the command below to deploy our Bicep template:
The image below shows the preview of the deployment:
Then we will execute the deployment. The image below shows the deployment output:
The deployment might take 5–7 minutes to complete.
Once the deployment completes, you can verify the resources in the Azure Portal:
You can go to the URL of the Azure App Service to confirm your deployment:
You can also access phpMyAdmin by adding /phpmyadmin to your URL site. In this case: http://azinsider.azurewebsites.net/phpmyadmin/
Source Code.
You can find the code of this solution in the following URL, feel free to contribute!
azinsider/application-workloads/wordpress-azure-app-service-2022 at main · daveRendon/azinsider
Contribute to daveRendon/azinsider development by creating an account on GitHub.
github.com
👉 Join the AzInsider email list here.
-Dave R.
所有评论(0)