Table of Contents
Introduction
Automating Azure Web App deployments with parameterized ARM templates allows you to create consistent and repeatable infrastructure. By using a single template file, you can deploy both an Azure App Service Plan and a Web App with custom names, locations, and pricing tiers. This eliminates manual configuration, reduces errors, and enables seamless integration into CI/CD pipelines.
Understanding the Core Components
A parameterized ARM template for a web app deployment typically contains these key sections:
- Parameters: This section defines the inputs you can provide at deployment time. Parameters make the template reusable for different environments (e.g., development, staging, production) without changing the template file itself. For a web app deployment, common parameters include
webAppName
,appServicePlanName
,skuName
(for the pricing tier), andlocation
. - Resources: This is the most crucial part of the template, where you define the Azure resources to be deployed. For this scenario, you will define two resources:
- App Service Plan: The resource type is
Microsoft.Web/serverfarms
. It represents the underlying infrastructure that hosts your web app. - Web App: The resource type is
Microsoft.Web/sites
. This is the application itself, which runs on the App Service Plan.
- App Service Plan: The resource type is
- Dependencies: The
dependsOn
property is essential for ensuring the correct deployment order. You must ensure the App Service Plan is created before the Web App, as the Web App requires a host to run on. The Web App resource will have adependsOn
property that references the App Service Plan. - Outputs: This optional section can be used to return values from the deployment, such as the web app’s URL or other key properties.
Step 1: Base Template (Hardcoded Example)
Here’s a simple ARM template that creates:
- An App Service Plan
- A Web App tied to that plan
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2022-09-01",
"name": "myAppServicePlan",
"location": "eastus",
"sku": {
"name": "F1",
"tier": "Free"
},
"properties": {}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "mywebappdemo123",
"location": "eastus",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'myAppServicePlan')]"
}
}
]
}
This works—but notice that both the plan name, app name, and location are hardcoded. Let’s fix that.
Step 2: Parameterized Template
Here’s the same template, but now it accepts parameters:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appServicePlanName": {
"type": "string",
"defaultValue": "myAppServicePlan",
"metadata": {
"description": "Name of the App Service Plan"
}
},
"webAppName": {
"type": "string",
"defaultValue": "myWebApp123",
"metadata": {
"description": "Name of the Web App"
}
},
"location": {
"type": "string",
"defaultValue": "eastus",
"allowedValues": [
"eastus",
"westus",
"centralus",
"uksouth"
],
"metadata": {
"description": "Location where resources will be deployed"
}
},
"skuName": {
"type": "string",
"defaultValue": "F1",
"allowedValues": [
"F1",
"B1",
"S1"
],
"metadata": {
"description": "Pricing tier for the App Service Plan"
}
}
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2022-09-01",
"name": "[parameters('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('skuName')]",
"tier": "Free"
},
"properties": {}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "[parameters('webAppName')]",
"location": "[parameters('location')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
}
}
]
}
Key Improvements
appServicePlanName
,webAppName
,location
, andskuName
are parameters.- You can now pass in values when you deploy.
- Default values are included for quick testing.
Step 3: Deploying the Template
You can deploy ARM templates using either Azure CLI or PowerShell.
Using Azure CLI
az group create --name MyResourceGroup --location eastus
az deployment group create \
--resource-group MyResourceGroup \
--template-file template.json \
--parameters appServicePlanName=myPlan \
webAppName=myUniqueWebApp123 \
location=westus \
skuName=B1
Using PowerShell
New-AzResourceGroup -Name MyResourceGroup -Location eastus
New-AzResourceGroupDeployment `
-ResourceGroupName MyResourceGroup `
-TemplateFile template.json `
-appServicePlanName "myPlan" `
-webAppName "myUniqueWebApp123" `
-location "westus" `
-skuName "B1"
Step 4: Putting It All Together
Now, you can use this template in:
- Dev/Test environments with cheaper SKUs (
F1
,B1
) - Production with higher SKUs (
S1
,P1v2
) - Different regions (
eastus
,uksouth
, etc.)
All without touching the JSON file just pass in parameters!
Conclusion
By parameterizing your ARM templates, you move from one-off deployments to scalable, reusable automation.
Instead of editing JSON each time, you pass in values when deploying making it perfect for CI/CD pipelines and enterprise-scale deployments.
Next time you need to spin up a new Web App in Azure, you’ll have a flexible template ready to go!
- Design