Frank Boucher ☁
Posted on September 3, 2020
In the previous tutorial, we were deploying only one resource. In most cases, you will be deploying many resources with one template, and it's important to have some control over the deployment.
In this tutorial, we will introduce some key features to keep your deployment in control.
Azure DevOps - DevOps Lab - Video
Dependency
Let's say we want to deploy a website, something simple. In Azure we will need two resources: an App Service and a Service plan. The Service plan needs to be created before the App Service. We know Azure will paralyzed as much as possible during a deployment, to make sure the order is respected we need to use dependsOn
.
Let's start a new ARM template. If you are using Visual Studio Code with the extension it will only take you a few clicks to get started.
- Create a new file named
temp.json
- Type "!arm" to get the skeleton of the template.
- In the
resources
section typearm-web-app
You should end-up with:
"resources": [
{
"name": "webApp1",
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"location": "[resourceGroup().location]",
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/appServicePlan1')]": "Resource",
"displayName": "webApp1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]"
],
"properties": {
"name": "webApp1",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]"
}
}
]
Notice the dependsOn
property? It's expecting a Service plan 'appServicePlan1'. If you try to validate or deploy this template it would fail because it's expecting a resource 'appServicePlan1'.
Let's add the service plan. With the extension just type "arm-plan". Now the template should look like this. And even if it's not following the best practices we learn, it is perfectly valid. Even more, we are sure that the service plan will always be deployed before the app service.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"functions": [],
"variables": {
},
"resources": [
{
"name": "webApp1",
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"location": "[resourceGroup().location]",
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/appServicePlan1')]": "Resource",
"displayName": "webApp1"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]"
],
"properties": {
"name": "webApp1",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]"
}
},
{
"name": "appServicePlan1",
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "F1",
"capacity": 1
},
"tags": {
"displayName": "appServicePlan1"
},
"properties": {
"name": "appServicePlan1"
}
}
],
"outputs": {}
}
Dependencies (aka dependsOn) are also very important when you have child resources. As an exemple our website could have a child resources of type sourceControl
. This is often used in continuous deployment to deploy the code. In those cases the sourceControl
would have a dependsOn
referencing his parent the App service.
To learn more about those particularities read Define the order for deploying resources in ARM templates from the Microsoft documentation.
Conditional
Now let's say when you are deploying in production, and in this case only, you would like have an extra storage for backups. In ARM this is relatively easy to do with the condition
property available in most of the resources.
Let's think about the storage used in the previous tutorial. By adding a property condition
and using the comparison functions for ARM templates we could make the storage account to be deploy only when the parameter environment
is equal to PROD.
"condition": "[equals(parameters('environment'), 'PROD')]",
Reference:
Posted on September 3, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.