In few of the previous blog posts, we discussed on what Azure ARM is and how it helps in the DevOps philosophy of Infrastructure-as-a-Code (IaaC). So we’ll build further on that knowledge. In this blog post, we’ll discuss how to create an Azure App service using ARM template.
We’ll be using Visual Studio 2017 for this post’s purpose. It is not necessary to use this, you can use just Visual Studio code and appropriate extension for ARM or you can use a simple notepad (as all ARM templates are JSON files in the end of the day) or any other editor of your choice. However, using Visual Studio 2017 further simplifies it.
First, open Visual Studio 2017 and create a new project:

We need to select Project type as Azure Resource Group. If it’s not coming for you, make sure that you have installed Azure SDK for Visual Studio on your machine.
For our purpose, let’s name project as DemoAzureAppService. You can also check option for ‘Create a new Git repository’ but it’s not required.

Next, we need to select the template type. Let’s start with a blank template and then click OK:

Next select azuredeploy.json file from the solution explorer. This is where we need to define the configuration for azure app service. It also creates other two files named as:
- azuredeploy.parameters.json: This file contains parameters or values for the configuration defined in azuredeploy.json file. This can be used to define app service name, standard tier, etc.
- Deploy-AzureResourceGroup.ps1: This is a powershell file which is executed during build to deploy the resource group defined. We do not need to edit this for the most of the configurations.
Now to the left of Visual Studio, we’ll need to right click resources and then add new resource:

For creating an app service, we need to also create an app service plan. So first we need to add azure app service plan from the new window and then click add:

Once we click add, it would add some configuration related data to the JSON file in central window. Let’s edit the variables section and add the below line:
"appHostingPlanNameVar": "[concat(parameters('appServicePlanName'),'-apps')]"
Once edited, it will look like:

Here, we have defined a variable named appHostingPlanNameVar and it will append string “-apps” (without quotes) to whatever the value defined for the appServicePlanName parameter. You need not do this, but you should always create variables to follow naming standards for creating resources in azure. Next, we need to edit the resources section to make sure that name should be based on the variable appHostingPlanNameVar. So let’s modify the same to as follows:
"name": "[variables('appHostingPlanNameVar')]"
Let’s go to resources again and this time add a web app from resources list and then click add:

This will again add a bunch of data to the existing JSON file. Now, let’s go to the parameters section and add the following:
"appServiceName": { "type": "string", "minLength": 1, "maxLength": 10 },
Depending upon whether you are adding it to the top or bottom, you may or may not need the last comma character in above code. The above code will allow us to define app service name using azuredeploy.paramerters.json file. It will also restrict name to a maximum of 10 characters length. Since we have now given the user the ability to define the app service name, let’s remove below line from the variables section (which is the auto generated app service name):
"webAppName": "[concat('webApp', uniqueString(resourceGroup().id))]"
Also, in the resources section, go to the web app section and edit the value for name tag as follows:
"name": "[parameters('appServiceName')]"
Make sure to do the same for properties section. This will configure app service to use same name as the value of the parameter appServiceName.
We can further define configuration like slots, app settings etc but let’s keep it simple for now. Next, we need to build the existing project. For this, you can either use Build from tabs in the Visual Studio or type Ctrl+Shift+B.
Once, the project is built, we can proceed to deploy it. Right click the project in the solution explorer window and select deploy and then select new:

At this point, Visual Studio is going to ask you to few details with respect to Azure subscription, resource group name, etc. Fill the appropriate details as shown:

Now, click on the edit parameters button,and submit appropriate values that we want for the deployment:

Do make sure that you provide a unique name for the app service. Click save and then deploy. In the build output, if all goes well, you should see the message like below:
19:20:56 - VERBOSE: 7:20:56 PM - Checking deployment status in 5 seconds 19:21:02 - VERBOSE: 7:21:02 PM - Checking deployment status in 5 seconds 19:21:07 - VERBOSE: 7:21:07 PM - Checking deployment status in 5 seconds 19:21:12 - VERBOSE: 7:21:12 PM - Checking deployment status in 5 seconds 19:21:18 - VERBOSE: 7:21:18 PM - Resource Microsoft.Web/serverfarms 'demo-apps' 19:21:18 - provisioning status is succeeded 19:21:18 - VERBOSE: 7:21:18 PM - Checking deployment status in 5 seconds 19:21:23 - VERBOSE: 7:21:23 PM - Resource Microsoft.Web/sites 'demoapp122' provisioning 19:21:23 - status is succeeded 19:21:23 - VERBOSE: 7:21:23 PM - Checking deployment status in 5 seconds 19:21:29 - 19:21:29 - DeploymentName : azuredeploy-0823-1350 19:21:29 - CorrelationId : a5b307f4-228a-4306-bd29-fe611c632a8a 19:21:29 - ResourceGroupName : appservicedemo 19:21:29 - ProvisioningState : Succeeded 19:21:29 - Timestamp : 8/23/2017 1:51:23 PM 19:21:29 - Mode : Incremental 19:21:29 - TemplateLink : 19:21:29 - TemplateLinkString : 19:21:29 - DeploymentDebugLogLevel : 19:21:29 - Parameters : {[appServiceName, Microsoft.Azure.Commands.ResourceMa 19:21:29 - nager.Cmdlets.SdkModels.DeploymentVariable], 19:21:29 - [appServicePlanName, Microsoft.Azure.Commands.Resourc 19:21:29 - eManager.Cmdlets.SdkModels.DeploymentVariable], 19:21:29 - [appServicePlanSkuName, Microsoft.Azure.Commands.Reso 19:21:29 - urceManager.Cmdlets.SdkModels.DeploymentVariable]} 19:21:29 - ParametersString : 19:21:29 - Name Type Value 19:21:29 - 19:21:29 - =============== ========================= 19:21:29 - ========== 19:21:29 - appServiceName String 19:21:29 - demoapp122 19:21:29 - appServicePlanName String demo 19:21:29 - 19:21:29 - appServicePlanSkuName String S1 19:21:29 - 19:21:29 - 19:21:29 - Outputs : {} 19:21:29 - OutputsString : 19:21:29 - 19:21:29 - 19:21:29 - 19:21:29 - Successfully deployed template 'azuredeploy.json' to resource group 'appservicedemo'.
If we take a look at azure portal, we can see the resources now:

Here’s a full copy of template, in case you keep getting JSON template invalid issues:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", | |
"contentVersion": "1.0.0.0", | |
"parameters": { | |
"appServiceName": { | |
"type": "string", | |
"minLength": 1, | |
"maxLength": 10 | |
}, | |
"appServicePlanName": { | |
"type": "string", | |
"minLength": 1 | |
}, | |
"appServicePlanSkuName": { | |
"type": "string", | |
"defaultValue": "S1", | |
"allowedValues": [ | |
"F1", | |
"D1", | |
"B1", | |
"B2", | |
"B3", | |
"S1", | |
"S2", | |
"S3", | |
"P1", | |
"P2", | |
"P3", | |
"P4" | |
], | |
"metadata": { | |
"description": "Describes plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/" | |
} | |
} | |
}, | |
"variables": { | |
"appHostingPlanNameVar": "[concat(parameters('appServicePlanName'),'-apps')]" | |
}, | |
"resources": [ | |
{ | |
"name": "[variables('appHostingPlanNameVar')]", | |
"type": "Microsoft.Web/serverfarms", | |
"location": "[resourceGroup().location]", | |
"apiVersion": "2015-08-01", | |
"sku": { | |
"name": "[parameters('appServicePlanSkuName')]" | |
}, | |
"dependsOn": [ ], | |
"tags": { | |
"displayName": "appServicePlan" | |
}, | |
"properties": { | |
"name": "[variables('appHostingPlanNameVar')]", | |
"numberOfWorkers": 1 | |
} | |
}, | |
{ | |
"name": "[parameters('appServiceName')]", | |
"type": "Microsoft.Web/sites", | |
"location": "[resourceGroup().location]", | |
"apiVersion": "2015-08-01", | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar'))]" | |
], | |
"tags": { | |
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar')))]": "Resource", | |
"displayName": "webApp" | |
}, | |
"properties": { | |
"name": "[parameters('appServiceName')]", | |
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appHostingPlanNameVar'))]" | |
} | |
}], | |
"outputs": {} | |
} |