Deploying Azure Firewall IP Group changes fails with conflict - azure

I am attempting to deploy an Azure Firewall with a Policy, a Rule and a set of IPGroups. When I deploy the ARM templates to start everything works.. Later If I want to change something in one of the IPGroups, and I try to deploy that IPGroup change, the Azure Deployment fails with a Status: Conflict with message:
{
"status": "Failed",
"error": {
"code": "ResourceDeploymentFailure",
"message": "The resource operation completed with terminal provisioning state 'Failed'."
}
}
I've attempted to both manage the IPGroups distinctly in their own ARM Template, and place them in with the Azure Policy Rule Collection ARM Template with a DependsOn to see if deploying them all together would help, but either way we just get "Conflict".. I Guess I am wondering what is the appropriate way to update an IPGroup that is a part of a Firewall Network rule? If I can't simply update the IPGroup?
Here is an example of my full ARM Template for my Policy with the IPGroups..
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"firewallPolicyName": {
"defaultValue": "[concat('onelucki-fw-parent-policy', uniqueString(resourceGroup().id))]",
"type": "String"
},
"DevSubnets": {
"defaultValue": "DevSubnets",
"type": "String"
},
"AzureSubnets": {
"defaultValue": "AzureSubnets",
"type": "String"
}
},
"variables": {
"fwPolicyName": "[parameters('firewallPolicyName')]"
},
"resources": [
{
"type": "Microsoft.Network/ipGroups",
"apiVersion": "2020-05-01",
"name": "AzureSubnets",
"location": "centralus",
"tags": { "Zone": "MixedZones" },
"properties": {
"ipAddresses": [
"10.99.1.1"
]
}
},
{
"type": "Microsoft.Network/ipGroups",
"apiVersion": "2020-05-01",
"name": "DevSubnets",
"location": "centralus",
"tags": { "Zone": "Dev" },
"properties": {
"ipAddresses": [
"10.99.2.2"
]
}
},
{
"type": "Microsoft.Network/firewallPolicies",
"apiVersion": "2020-11-01",
"name": "[parameters('firewallPolicyName')]",
"location": "centralus",
"properties": {
"sku": {
"tier": "Standard"
},
"threatIntelMode": "Alert"
}
},
{
"type": "Microsoft.Network/firewallPolicies/ruleCollectionGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('firewallPolicyName'), '/DefaultNetworkRuleCollectionGroup')]",
"location": "westus",
"dependsOn": [
"[resourceId('Microsoft.Network/ipGroups', parameters('AzureSubnets'))]",
"[resourceId('Microsoft.Network/ipGroups', parameters('DevSubnets'))]",
"[resourceId('Microsoft.Network/firewallPolicies', parameters('firewallPolicyName'))]"
],
"properties": {
"priority": 200,
"ruleCollections": [
{
"ruleCollectionType": "FirewallPolicyFilterRuleCollection",
"action": {
"type": "Allow"
},
"rules": [
{
"ruleType": "NetworkRule",
"name": "DemoRule",
"ipProtocols": [
"TCP"
],
"sourceAddresses": [],
"sourceIpGroups": [
"/subscriptions/<subscriptionIDHere>/resourceGroups/onelucki-fw/providers/Microsoft.Network/ipGroups/DevSubnets"
],
"destinationAddresses": [],
"destinationIpGroups": [
"/subscriptions/<subscriptionIDHere>/resourceGroups/onelucki-fw/providers/Microsoft.Network/ipGroups/AzureSubnets"
],
"destinationFqdns": [],
"destinationPorts": [
"135",
"445"
]
}
],
"name": "DemoDeployRuleCollection",
"priority": 1300
}
]
}
}
]
}

IP groups need to be deployed one at a time. Also the firewall policy needs a depends on the IP groups being used despite it not having them listed.
The deploy of the IP groups seems to do some validation/update on the firewall policy during deploy.
Deploy nested resources in Azure using DependsOn

Related

Cannot create azure private dns A record with its ip by using ARM template

I am trying to create an A record in an Azure private DNS Zone with an ARM template. The creation of the record is successful but without its IP, neither TTL.
My template is below:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"DNSZoneName": {
"type": "string",
"defaultValue": "privatelink.database.windows.net",
"metadata": {
"description": "The name of the DNS zone. Must have at least 2 segements, e.g. hostname.org"
}
},
"newRecordName": {
"type": "string",
"defaultValue": "pe-sql3",
"metadata": {
"description": "The name of the DNS record to be created. The name is relative to the zone, not the FQDN."
}
}
},
"resources": [
{
"type": "Microsoft.Network/privateDnsZones/A",
"apiVersion": "2018-09-01",
"name": "[concat(parameters('DNSZoneName'), '/', parameters('newRecordName'))]",
"location": "global",
"properties": {
"TTL": 3600,
"ARecords": [
{
"ipv4Address": "10.0.0.1"
}
]
}
}
]
}
My command is New-AzResourceGroupDeployment -ResourceGroupName myRg -TemplateFile deploy.json
Here is the screenshot of the A record from the portal:
Any idea?
I think you have a race condition. Add a dpendsOn.
"dependsOn": [
"[parameters('DNSZoneName')]"
],
Like this:
[EDIT: specify the DNS Zone resource as well]
"resources": [
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "2018-05-01",
"name": "[parameters('DNSZoneName')]",
"location": "global"
},
{
"type": "Microsoft.Network/privateDnsZones/A",
"apiVersion": "2018-09-01",
"name": "[concat(parameters('DNSZoneName'), '/', parameters('newRecordName'))]",
"location": "global",
"dependsOn": [
"[parameters('DNSZoneName')]"
],
"properties": {
"TTL": 3600,
"ARecords": [
{
"ipv4Address": "10.0.0.1"
}
]
}
}
]
I was writing TTL and ARecords in capital letter. That should have been with ttl and aRecords:
"properties": {
"ttl": 3600,
"aRecords": [
{
"ipv4Address": "1.2.3.4"
}
]
}
}
But the thing is that when it is written with capital letters, the REST API doesn’t throw error and accept the request. Normally, it should return http 400 error.
Anyway, my problem is solved.

ARM template deployment of Microsoft.Web/sites/hostNameBindings keep giving me conflict error

I am trying to deploy app services but I keep getting deployment failure Microsoft.Web/sites/hostNameBindings
Message: Cannot modify this site because another operation is in progress. OperationName: RegisterTrafficManagerProfile, CreatedTime: 5/14/2021 12:03:05 AM, , EntityType: 1.
I get this error intermittently.
I read one of the stack overflow answers that it seems Traffic Manager causes a problem with the asynchronous hostNameBindings iteration operation.
Which can be resolved by specifying a synchronous copy using "mode": "serial" mode with "batchsize": 1,
I tried this solution but I still get this conflict error, not sure why? anyone ran into same issue where after synchronising the copy getting above error?
Recently we had changes to our template to deploy traffic manager endpoints as separate resource which caused the process to take longer, Does increase in process time can cause conflict? what can be other reasons for this failure?
Any insights into this will be helpful. I am quite new to working on app service arm template
EDIT My current arm template I am just showing hostname bindings and traffic manager profiles
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2016-03-01",
"copy": {
"name": "hostNameBindingLoop",
"mode": "serial",
"batchSize": 1,
"count": "[length(variables('appServicePlanLocations'))]"
},
"name": "[concat(variables('websiteName') [copyIndex()], '/', parameters('cName'))]",
"location": "[vaiables('appServicePlanLocations')[copyIndex()]]",
"properties": {
"sslState": "SniEnabled",
"thumbprint": "[reference(resourceId('Microsoft.Web/certificates', variables('xyzCertName')[copyIndex()])).Thumbprint]"
},
"dependsOn": [
"[concat('Microsoft.Web/certificates/',variables('xyzCertName'[copyIndex()])]",
],
},
{
"type": "Microsoft.Network/trafficManagerProfiles",
"apiVersion": "2018-08-01",
"name": "[parameters('trafficManagerName')]",
"location": "global",
"properties": {
"profileStatus": "Enabled",
"trafficRoutingMethod": "Performance",
"dnsConfig": {
"relativeName": "[parameters('uniqueDnsName')]",
"ttl": 300
},
"monitorConfig": {
"protocol": "HTTPS",
"port": 443,
"path": "/"
}
"endpoints": [],
"trafficViewEnrollmentStatus": "Disabled
}
},
{
"type": "Microsoft.Network/trafficManagerProfiles/azureEndpoints",
"apiVersion": "2018-08-01",
"name": "[concat(variables('trafficManager'),'/',variables('websiteName'), copyIndex(1))]",
"location": "global",
"dependsOn": [
"[concat('Microsoft.Network/trafficManagerProfiles/', variables('trafficManager'))]"
],
"properties": {
"targetResourceId": "[concat('Microsoft.Web/sites/',variables('websiteName')[copyIndex()])]",'
"endpointStatus": "Enabled",
"endpointLocation": "[vaiables('appServicePlanLocations')[copyIndex()]]"
},
"copy": {
"name": "trafficManagerEndPointLoop",
"mode": "serial",
"batchSize": 1,
"count": "[length(variables('appServicePlanLocations'))]"
}
}
I assume that you would like to create an Azure Traffic Manager profile with an App Service Behind It. Here is a template for your reference. This automatically provisions a custom domain xxxx.trafficmanager.net in the custom domains settings of your Azure app service.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"uniqueDnsName": {
"type": "string",
"metadata": {
"description": "Relative DNS name for the traffic manager profile, resulting FQDN will be <uniqueDnsName>.trafficmanager.net, must be globally unique."
}
},
"uniqueDnsNameForWebApp": {
"type": "string",
"metadata": {
"description": "Relative DNS name for the WebApps, must be globally unique. An index will be appended for each Web App."
}
},
"webServerName": {
"type": "string",
"metadata": {
"description": "Name of the App Service Plan that is being created"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"trafficManagerName": {
"type": "string",
"metadata": {
"description": "Name of the trafficManager being created"
}
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2019-08-01",
"name": "[parameters('webServerName')]",
"location": "[parameters('location')]",
"sku": {
"name": "S1",
"tier": "Standard"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"name": "[parameters('uniqueDnsNameForWebApp')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms/',parameters('webServerName'))]"
],
"properties": {
"serverFarmId": "[parameters('webServerName')]"
}
},
{
"type": "Microsoft.Network/trafficManagerProfiles",
"apiVersion": "2018-08-01",
"name": "[parameters('trafficManagerName')]",
"location": "global",
"properties": {
"profileStatus": "Enabled",
"trafficRoutingMethod": "Priority",
"dnsConfig": {
"relativeName": "[parameters('uniqueDnsName')]",
"ttl": 30
},
"monitorConfig": {
"protocol": "HTTPS",
"port": 443,
"path": "/"
}
}
},
{
"type": "Microsoft.Network/trafficManagerProfiles/azureEndpoints",
"apiVersion": "2018-08-01",
"name": "[concat(parameters('trafficManagerName'),'/',parameters('uniqueDnsNameForWebApp'))]",
"location": "global",
"dependsOn": [
"[resourceId('Microsoft.Network/trafficManagerProfiles/',parameters('trafficManagerName'))]",
"[resourceId('Microsoft.Web/sites/',parameters('uniqueDnsNameForWebApp'))]"
],
"properties": {
"targetResourceId": "[resourceId('Microsoft.Web/sites/', parameters('uniqueDnsNameForWebApp'))]",
"endpointStatus": "Enabled"
}
}
]
}

Azure FrontDoor: how to set up backendPool with multiple instance inside?

I started Infrastructure as Code with ARM Template and previously all my deployment was made with Powershell. Hope you can help me to fix this issue.
I would like to deploy {2 app services + Azure FrontDoor]. In FrontDoor-Backendpool I want to define the 2 appservices. Below my code:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "array",
"metadata": {
"description": "array of region"
},
"defaultValue": [
"centralus",
"eastus"
]
},
"Stage": {
"type": "string",
"metadata": {
"description": "Stage dev, prod"
},
"allowedValues": [
"Dev",
"Prod"
],
"defaultValue": "Dev"
}
},
"functions": [],
"variables": {
"appServicePlanName": "[concat('AppServicePlan-', parameters('Stage'),'-')]",
"appServiceName": "[concat('AppService-', parameters('Stage'), '-')]",
"frontDoorName": "[concat('FrontDoor-', parameters('Stage'), uniqueString(resourceGroup().id))]"
},
"resources": [
{ // App Service Plan
"type": "Microsoft.Web/serverfarms",
"name": "[concat(variables('appServicePlanName'),parameters('location')[copyIndex()])]",
"apiVersion": "2018-02-01",
"copy": {
"count": "[length(parameters('location'))]",
"name": "copy multiple"
},
"location": "[parameters('location')[copyIndex()]]",
"sku": {
"name": "F1",
"capacity": 1
},
"tags": {
"cost": "[parameters('Stage')]"
},
"properties": {
"name": "[concat(variables('appServicePlanName'),parameters('location')[copyIndex()])]"
}
},
{ // App Services
"type": "Microsoft.Web/sites",
"name": "[concat(variables('appServiceName'), parameters('location')[copyIndex()])]",
"apiVersion": "2018-11-01",
"copy": {
"name": "Copy website",
"count": "[length(parameters('location'))]"
},
"location": "[parameters('location')[copyIndex()]]",
"tags": {
"cost": "[parameters('Stage')]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', concat(variables('appServicePlanName'),parameters('location')[copyIndex()]))]"
],
"properties": {
"name": "[concat(variables('appServiceName'), parameters('location')[copyIndex()])]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', concat(variables('appServicePlanName'),parameters('location')[copyIndex()]))]"
}
},
{ // Front Door
"type": "Microsoft.Network/frontDoors",
"apiVersion": "2020-05-01",
"name": "[variables('frontDoorName')]",
"location": "global",
"properties": {
"routingRules": [
{
"name": "routingRule1",
"properties": {
"frontendEndpoints": [
{
"id": "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', variables('frontDoorName'), 'frontendEndpoint1')]"
}
],
"acceptedProtocols": [
"Http",
"Https"
],
"patternsToMatch": [
"/*"
],
"routeConfiguration": {
"#odata.type": "#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration",
"forwardingProtocol": "MatchRequest",
"backendPool": {
"id": "[resourceId('Microsoft.Network/frontDoors/backendPools', variables('frontDoorName'), 'backendPool1')]"
}
},
"enabledState": "Enabled"
}
}
],
"healthProbeSettings": [
{
"name": "healthProbeSettings1",
"properties": {
"path": "/",
"protocol": "Http",
"intervalInSeconds": 120
}
}
],
"loadBalancingSettings": [
{
"name": "loadBalancingSettings1",
"properties": {
"sampleSize": 4,
"successfulSamplesRequired": 2
}
}
],
"backendPools": [
{
"id": "backendPool1",
"name": "backendPool1",
"properties": {
"copy": [
{
"name": "backends",
"count": "[length(parameters('location'))]",
"input": {
"address": "[concat(variables('appServiceName'), parameters('location')[copyIndex()], '.azurewebsites.net') ]",
"httpPort": 80,
"httpsPort": 443,
"weight": 50,
"priority": 1,
"enabledState": "Enabled"
}
}
],
"loadBalancingSettings": {
"id": "[resourceId('Microsoft.Network/frontDoors/loadBalancingSettings', variables('frontDoorName'), 'loadBalancingSettings1')]"
},
"healthProbeSettings": {
"id": "[resourceId('Microsoft.Network/frontDoors/healthProbeSettings', variables('frontDoorName'), 'healthProbeSettings1')]"
}
}
}
],
"frontendEndpoints": [
{
"name": "frontendEndpoint1",
"properties": {
"hostName": "[concat(variables('frontDoorName'), '.azurefd.net')]",
"sessionAffinityEnabledState": "Enabled"
}
}
],
"enabledState": "Enabled"
}
}
],
"outputs": {}
}
As you can see i iterate on paramater location to create my AppService Plan and AppService and it worked well. So I thought to do same for BackEndpool.
Here part of code which break my head
address": "[concat(variables('appServiceName'), parameters('location')[copyIndex()], '.azurewebsites.net') ]",
Something is wrong inside but I have no idea why.
Error retuned is:
Error: Code=InvalidTemplate; Message=Deployment template language expression evaluation
failed: 'The template language function 'copyIndex' has an invalid argument. The provided copy name '' doesn't exist in the resource.
Please see https://aka.ms/arm-copy for usage details.'. Please see https://aka.ms/arm-template-expressions for usage details.
I take my inspiration from official MS documentation link from MS
Any idea on how I can fix it ?
Thx
You need to include the copy name property in the call to copyIndex in the backendPools part. That is why is says "The provided copy name '' doesn't exist". The property copy is treated a little differently than the resource copy.
"The loopName property enables you to specify whether copyIndex is referring to a resource iteration or property iteration. If no value is provided for loopName, the current resource type iteration is used. Provide a value for loopName when iterating on a property."
Source: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-numeric#copyindex
parameters('location')[copyIndex('backends')]

Container Instance only runs on first deployment from ARM template

I'm attempting to create a Storage Account with a file share via an ARM template. To do this, I'm creating the Storage Account and then running a az CLI command within a container instance, as described here.
The template deploys just fine, but the trouble is that the container is only started on the first run. Subsequent deployments do not result in the container instance being started, and thus if the file share has been removed (humans make mistakes), it's not recreated.
I can't use a complete deployment because there are other resources in the Resource Group.
I have consulted to documentation, but there doesn't seem to be anything about this in there.
Is there anyway to tell the container instance to always start?
Here is the example template that I am using -
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS"
],
"metadata": {
"description": "Storage Account type"
}
},
"storageAccountName": {
"type": "string",
"defaultValue": "[uniquestring(resourceGroup().id)]",
"metadata": {
"description": "Storage Account Name"
}
},
"fileShareName": {
"type": "string",
"metadata": {
"description": "File Share Name"
}
},
"containerInstanceLocation": {
"type": "string",
"defaultValue": "[parameters('location')]",
"allowedValues": [
"westus",
"eastus",
"westeurope",
"southeastaisa",
"westus2"
],
"metadata": {
"description": "Container Instance Location"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {
"image": "microsoft/azure-cli",
"cpuCores": "1.0",
"memoryInGb": "1.5",
"containerGroupName": "createshare-containerinstance",
"containerName": "createshare"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageAccountName')]",
"apiVersion": "2017-10-01",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"kind": "Storage",
"properties": {}
},
{
"name": "[variables('containerGroupName')]",
"type": "Microsoft.ContainerInstance/containerGroups",
"apiVersion": "2018-02-01-preview",
"location": "[parameters('containerInstanceLocation')]",
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
],
"properties": {
"containers": [
{
"name": "[variables('containerName')]",
"properties": {
"image": "[variables('image')]",
"command": [
"az",
"storage",
"share",
"create",
"--name",
"[parameters('fileShareName')]"
],
"environmentVariables": [
{
"name": "AZURE_STORAGE_KEY",
"value": "[listKeys(parameters('storageAccountName'),'2017-10-01').keys[0].value]"
},
{
"name": "AZURE_STORAGE_ACCOUNT",
"value": "[parameters('storageAccountName')]"
}
],
"resources": {
"requests": {
"cpu": "[variables('cpuCores')]",
"memoryInGb": "[variables('memoryInGb')]"
}
}
}
}
],
"restartPolicy": "OnFailure",
"osType": "Linux"
}
}
]
}
What if you manually delete the ACI from Azure portal or trough az cli in between using az container delete. As I understand Azure Container Instances are meant to be disposable. I usually just delete the old container when I want to deploy new one. Of course this is done usually by CI&CD pipeline like Jenkins.
EDIT:
ARM-template only starts the container if it doesn't find the resource but because it does find the ACI it does nothing. IMHO you should not use ARM-Templates for container management.

Tags Not Being Deployed to Server Farm with Azure ARM template

EDIT 11/15/2016: This was a bug in Azure which was fixed a couple of days ago.
Original post:
I'm trying to create several app services which depend on a server farm. I'm using an ARM template to deploy it. I'm using the same tags and tag format on every other resource in the template and they are getting created, but for some reason the tags on the server farm aren't. I can create the tags on the server farm through the Azure Portal and the Resource Explorer, but not through the ARM template.
Here's part of my resources section:
{
"comments": "",
"type": "Microsoft.Web/serverfarms",
"sku": {
"name": "S3",
"tier": "Standard",
"size": "S3",
"family": "S",
"capacity": 1
},
"tags": {
"tag1": "[parameters('tag1Value')]",
"tag2": "[parameters('tag2Value')]",
"tag3": "[parameters('tag3Value')]",
"tag4": "[parameters('tag4Value')]",
"tag5": "[parameters('tag4Value')]",
"tag6": "[parameters('tag6Value')]",
"tag7": "[parameters('tag7Value')]"
},
"name": "[variables('serverFarmName')]",
"apiVersion": "2015-08-01",
"location": "[parameters('location')]",
"properties": {
"name": "[variables('serverFarmName')]",
"numberOfWorkers": 1
},
"dependsOn": []
},
[...]
Any known issues with this? Do I have the tags in the wrong place?
Edit 8/8/2016:
Deploying just a server farm works correctly, but as soon as I add a site to that server farm the tags aren't deployed correctly. Here's what happens: Deployment starts, the server farm is created. Before the site is created I can rush into the Azure portal and see the tags created correctly on the server farm. As soon as the site is created I refresh, go back into the server farm, and the tags have disappeared.
It works fine on my side, you can try to leverage the Azure Resource Group project in Visual studio as mentioned at https://blogs.msdn.microsoft.com/kaevans/2015/11/22/creating-arm-templates-with-azure-resource-explorer/.
Here is my simple test template for your information:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tag1Value": { "type": "string" },
"tag2Value": { "type": "string" },
"tag3Value": { "type": "string" },
"tag4Value": { "type": "string" },
"tag5Value": { "type": "string" },
"tag6Value": { "type": "string" },
"tag7Value": { "type": "string" },
"garysfName": {
"type": "string",
"minLength": 1
},
"garysfSKU": {
"type": "string",
"allowedValues": [
"Free",
"Shared",
"Basic",
"Standard"
],
"defaultValue": "Free"
},
"garysfWorkerSize": {
"type": "string",
"allowedValues": [
"0",
"1",
"2"
],
"defaultValue": "0"
}
},
"variables": {
},
"resources": [
{
"name": "[parameters('garysfName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[resourceGroup().location]",
"apiVersion": "2014-06-01",
"dependsOn": [ ],
"tags": {
"displayName": "garysf",
"tag1": "[parameters('tag1Value')]",
"tag2": "[parameters('tag2Value')]",
"tag3": "[parameters('tag3Value')]",
"tag4": "[parameters('tag4Value')]",
"tag5": "[parameters('tag4Value')]",
"tag6": "[parameters('tag6Value')]",
"tag7": "[parameters('tag7Value')]"
},
"properties": {
"name": "[parameters('garysfName')]",
"sku": "[parameters('garysfSKU')]",
"workerSize": "[parameters('garysfWorkerSize')]",
"numberOfWorkers": 1
}
},
{
"name": "[variables('garyarmwebappName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('garysfName'))]"
],
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('garysfName'))]": "Resource",
"displayName": "garyarmwebapp"
},
"properties": {
"name": "[variables('garyarmwebappName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', parameters('garysfName'))]"
}
}
],
"outputs": {
}
}
And the parameters JSON file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"tag1Value": { "value": "tag11" },
"tag2Value": { "value": "tag22" },
"tag3Value": { "value": "tag33" },
"tag4Value": { "value": "tag44" },
"tag5Value": { "value": "tag55" },
"tag6Value": { "value": "tag66" },
"tag7Value": { "value": "tag77" },
"garysfName": {
"value": "garyserverfarms"
}
}
}
And you can refer to https://ms.portal.azure.com/?flight=1&flight.browsegrid2=true&flight.pov2=true&flight.resourcemenuperf=true#blade/HubsExtension/SubscriptionTagsListBlade to check the tag list on Azure portal.

Resources