Automating Azure Web App Deployment with Parameterized ARM Templates
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
dependsOnproperty 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 adependsOnproperty 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, andskuNameare 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!





