Infrastructure as code patterns have allowed us to create complex application infrastructure to support a wide variety of use cases. These applications, consisting of many “services” or “components” working together, give way to the desire to be able to interact with the set of resources, rather than individuals. Take, for example, an application that consists of many microservices. For the sake of argument, let’s assume that these microservices are all Azure Web Apps running on a single app service plan. As part of a deployment plan, I may have need to restart all the web applications to facilitate a code deployment. The current solution in Azure is to simply go through all the Azure Web Apps, restarting them one-by-one. While this can be achieved through both the portal, and via scripting using the various APIs, this approach leaves a bit to be desired.
Enter Azure Custom Actions. Part of the Azure Custom Providers documentation section, actions allow you to extend existing Azure APIs. At it’s basic level, actions consist of two parts:
The idea here is that your infrastructure as code can now bundle in “meta-actions” (for lack of a better word) that allow administrators to interact with sets of resources. Let’s explore this concept by trying to create an Azure Custom Action that restarts all the web apps in a particular resource group. Here is a visual representation of what we are trying to do:
In this part, we will work up a basic template of the Azure Resources we will want to interact with.
Here is a look at our base template. I’m keeping it super simple so we can focus on adding the custom action.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"functions": [],
"variables": {
"location":"[resourceGroup().location]",
"aspName":"[guid(resourceGroup().name,'asp')]",
"web1Name":"[guid(resourceGroup().name,'web1')]",
"web2Name":"[guid(resourceGroup().name,'web2')]"
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2021-02-01",
"name":"[variables('aspName')]",
"location": "[variables('location')]",
"sku": {
"name":"S1"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name":"[variables('web1Name')]",
"location":"[variables('location')]",
"dependsOn":[
"[variables('aspName')]"
],
"properties":{
"serverFarmId":"[resourceId('Microsoft.Web/serverfarms',variables('aspName'))]"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2021-02-01",
"name":"[variables('web2Name')]",
"location":"[variables('location')]",
"dependsOn":[
"[variables('aspName')]"
],
"properties":{
"serverFarmId":"[resourceId('Microsoft.Web/serverfarms',variables('aspName'))]"
}
}
],
"outputs": {}
}
After we create a resource group and deploy this template, we can see the following components deployed.
Perfect. In part 2, we can move on to creating the backend for our custom action.
 
Shamir Charania, a seasoned cloud expert, possesses in-depth expertise in Amazon Web Services (AWS) and Microsoft Azure, complemented by his six-year tenure as a Microsoft MVP in Azure. At Keep Secure, Shamir provides strategic cloud guidance, with senior architecture-level decision-making to having the technical chops to back it all up. With a strong emphasis on cybersecurity, he develops robust global cloud strategies prioritizing data protection and resilience. Leveraging complexity theory, Shamir delivers innovative and elegant solutions to address complex requirements while driving business growth, positioning himself as a driving force in cloud transformation for organizations in the digital age.