How to fix deployIfNotExists policy for Key Vault - json

Trying to create a DeployIfNotExists policy that will automatically set the "networkACLs" properties on all key vaults but after battling with that for a couple of weeks, I decided to try to manipulate a simpler boolean property instead of a complex object property. The property I chose is "enabledForDeployment". The policy does properly find the non-compliant key vaults but the deployment is not working.
Once I get this "easy" policy working, I will go back and attempt to set the "networkACLs" property to the following:
"networkAcls": {
"defaultAction": "Deny",
"bypass": "None",
"ipRules": [
{"value": "1.1.1.0/24"},
{"value":"2.2.2.0/24"}
],
"virtualNetworkRules": []
}
The policy code is below...
{
"mode": "All",
"policyRule": {
"if": {
"allof": [
{
"field": "type",
"equals": "Microsoft.KeyVault/vaults"
},
{
"not": {
"field": "Microsoft.KeyVault/vaults/enabledForDeployment",
"equals": true
}
}
]
},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.KeyVault/vaults",
"name": "[field('name')]",
"existenceCondition": {
"field": "Microsoft.KeyVault/vaults/enabledForDeployment",
"equals": "true"
},
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"deployment": {
"location": "[field('location')]",
"properties": {
"mode": "incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"Name": {
"type": "string"
},
"location": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2018-02-14",
"name": "[parameters('Name')]",
"location": "[parameters('location')]",
"properties": {
"enabledForDeployment": true
}
}
],
"outputs": {
"policy": {
"type": "string",
"value": "done"
}
}
},
"parameters": {
"location": {
"value": "[field('location')]"
},
"Name": {
"value": "[field('name')]"
}
}
}
}
}
}
},
"parameters": {}
}
I'm currently getting an "internalServerError" message. Any ideas?

#Kemley you are correct. My ARM template was incorrect. It was missing a few required fields (Sku, Access Policies, etc). Below is the final policy that updates the NetworkACLs if the default network allow all is set.
{
"properties": {
"displayName": "Vzn Deploy Key Vault NetworkAcls defaultAction",
"policyType": "Custom",
"mode": "All",
"description": "Removes the default allow all networks. Manually sets 2 firewall rules",
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the policy"
},
"allowedValues": [
"deployIfNotExists",
"disabled"
],
"defaultValue": "deployIfNotExists"
}
},
"policyRule": {
"if": {
"field": "type",
"equals": "Microsoft.KeyVault/vaults"
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.KeyVault/vaults",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395"
],
"existenceCondition": {
"field": "Microsoft.KeyVault/vaults/networkAcls.defaultAction",
"equals": "Deny"
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyvaultname": {
"type": "string"
},
"locationname": {
"type": "string"
},
"skuname": {
"type": "string"
},
"accessPoliciesname": {
"type": "array"
}
},
"resources": [
{
"name": "[parameters('keyvaultname')]",
"location": "[parameters('locationname')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2018-02-14",
"properties": {
"tenantId": "be42d65b-eb64-4a64-8aa3-ae47eef3af3e",
"accessPolicies": "[parameters('accessPoliciesname')]",
"sku": {
"name": "[parameters('skuname')]",
"family": "A"
},
"networkAcls": {
"defaultAction": "Deny",
"bypass": "None",
"ipRules": [
{
"value": "1.2.3.0/27"
},
{
"value": "1.5.6.0/24"
}
]
}
}
}
]
},
"parameters": {
"keyvaultname": {
"value": "[field('name')]"
},
"locationname": {
"value": "[field('location')]"
},
"skuname": {
"value": "[field('Microsoft.KeyVault/vaults/sku.name')]"
},
"accessPoliciesname": {
"value": "[field('Microsoft.KeyVault/vaults/accessPolicies')]"
}
}
}
},
"name": "[field('name')]"
}
}
}
}
}

I would recommend checking your ARM template to make sure that it is correct. Sometimes when you use the export a template function the ARM template might not work without testing. If you have an issue with the ARM template, I would direct your questions to them

Related

Azure Function App new JSON with only a few properties

I am struggling of finding a feasible solution for my Azure Logic App.
A HTTP Request-action call will list the virtual networks of an Azure subscription.
The response look somehow like this:
{
"value": [
{
"name": "virtualNetworkName1",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName1/providers/Microsoft.Network/virtualNetworks/virtualNetworkName1",
"etag": "W/\"11111-1111-111\"",
"type": "Microsoft.Network/virtualNetworks",
"location": "eastus",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "111-1111-11111",
"addressSpace": {
"addressPrefixes": [
"192.168.0.0/25"
]
}
}
},
{
"name": "virtualNetworkName2",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName2/providers/Microsoft.Network/virtualNetworks/virtualNetworkName2",
"etag": "W/\"22222-2222-222\"",
"type": "Microsoft.Network/virtualNetworks",
"location": "westeurope",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "222-2222-22222",
"addressSpace": {
"addressPrefixes": [
"192.168.1.0/24"
]
}
}
}
]
}
The resonse has even more properties which aren't necessary.
Regarding to this, I would like to use the HTTP Response-action in a JSON format with only a few properties:
Name
Id
Location
Like this:
[
{
"name": "virtualNetworkName1",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName1/providers/Microsoft.Network/virtualNetworks/virtualNetworkName1",
"location": "eastus"
},
{
"name": "virtualNetworkName2",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName2/providers/Microsoft.Network/virtualNetworks/virtualNetworkName2",
"location": "westeurope"
}
]
Is it possible to realize it with only Logic App native actions?
I have reproduced in my environment and got expected results as below:
Firstly, I have initialized your output in a variable and then used parse Json and compose to get required output:
Parse Json Schema:
{
"properties": {
"value": {
"items": {
"properties": {
"id": {
"type": "string"
},
"location": {
"type": "string"
},
"name": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
Output:
First json Output:
Second one:
Code view of Logic app:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"value": [
{
"etag": "W/\"11111-1111-111\"",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName1/providers/Microsoft.Network/virtualNetworks/virtualNetworkName1",
"location": "eastus",
"name": "virtualNetworkName1",
"properties": {
"addressSpace": {
"addressPrefixes": [
"192.168.0.0/25"
]
},
"provisioningState": "Succeeded",
"resourceGuid": "111-1111-11111"
},
"type": "Microsoft.Network/virtualNetworks"
},
{
"etag": "W/\"22222-2222-222\"",
"id": "/subscriptions/111-222-333/resourceGroups/resourceGroupName2/providers/Microsoft.Network/virtualNetworks/virtualNetworkName2",
"location": "westeurope",
"name": "virtualNetworkName2",
"properties": {
"addressSpace": {
"addressPrefixes": [
"192.168.1.0/24"
]
},
"provisioningState": "Succeeded",
"resourceGuid": "222-2222-22222"
},
"type": "Microsoft.Network/virtualNetworks"
}
]
},
"runAfter": {},
"type": "Compose"
},
"For_each": {
"actions": {
"Compose_2": {
"inputs": {
"id": "#items('For_each')?['id']",
"location": "#items('For_each')?['location']",
"name": "#items('For_each')?['name']"
},
"runAfter": {},
"type": "Compose"
}
},
"foreach": "#body('Parse_JSON')?['value']",
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Foreach"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"value": {
"items": {
"properties": {
"id": {
"type": "string"
},
"location": {
"type": "string"
},
"name": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
Now you will get required fields as I have got.

How to use parameter value inside the siteconfig in ARM template?

I have below code for the create function app :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"storage_account_name": {
"type": "string",
"defaultValue": "test"
},
"location": {
"defaultValue": "[resourceGroup().location]",
"type": "string"
},
"App_Plan_Name": {
"type": "string",
"defaultValue": "test1"
},
"Function_App_Name": {
"type": "string",
"defaultValue": "funapwp11"
},
"AI_Name": {
"type": "string",
"defaultValue": "appinsiwghts"
},
"Appsetting_For_Fun_App": {
"type": "object",
"defaultValue": {
"client_id": "",
"client_secret": "",
"subscription_id": "",
"tenant_id": "",
"FUNCTIONS_EXTENSION_VERSION": "~4",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
},
"variables": {
"unique_Storage_Name": "[concat(parameters('storage_account_name'),uniqueString(resourceGroup().id))]",
//"Unique_App_Service_Name": "[concat(parameters('App_Service_Name'),uniqueString(resourceGroup().id))]",
"Unique_App_Plan_Name": "[concat(parameters('App_Plan_Name'),uniqueString(resourceGroup().id))]",
"Unique_Fun_App_Name": "[concat(parameters('Function_App_Name'),uniqueString(resourceGroup().id))]",
"Unique_AI_Name": "[concat(parameters('AI_Name'),uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"location": "[parameters('location')]",
"name": "[variables('Unique_Fun_App_Name')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('Unique_App_Plan_Name'))]",
"[resourceId('Microsoft.Storage/storageAccounts',variables('unique_Storage_Name'))]",
"[resourceId('Microsoft.Insights/components',variables('Unique_AI_Name'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms',variables('Unique_App_Plan_Name'))]",
"httpsOnly": true,
"enabled": true,
"adminEnabled": true,
"sku": "Basic",
"siteProperties": {
"properties": [
{
"name": "LinuxFxVersion",
"value": "Python|3.9"
},
{
"name": "WindowsFxVersion",
"value": null
}
]
},
"siteConfig": {
"linuxFxVersion": "Python|3.9",
"alwaysOn": true,
"pythonVersion": "3.9",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', variables('Unique_AI_Name'))).InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference(resourceId('Microsoft.Insights/components',variables('Unique_AI_Name')),'2020-02-02-preview').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('Unique_Storage_Name'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('Unique_Storage_Name')), '2021-08-01').keys[0].value)]"
}
]
}
}
}
]
}
I want use Appsetting_For_Fun_App parameter inside the properties >> siteConfig >> appSettings.
Parameter:
"Appsetting_For_Fun_App": {
"type": "object",
"defaultValue": {
"client_id": "",
"client_secret": "",
"subscription_id": "",
"tenant_id": "",
"FUNCTIONS_EXTENSION_VERSION": "~4",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
I need like that
"appSettings": [
{
"name": "[parameters('Appsetting_For_Fun_App')]",
"value": "[parameters('Appsetting_For_Fun_App')]"
},
I have tried multiple way but no luck.
You can refer the question: Azure resource manager template website app settings
Two options I can think of:
format the parameter as an object array - then no transform is needed in the template...
"parameters": {
"Appsetting_For_Fun_App": {
"type": "array",
"defaultValue": [
{
"name": "client_id",
"value": ""
},
{
"name": "client_secret",
"value": ""
},
{
"name": "subscription_Id",
"value": ""
}
]
}
And then on the web app:
"siteConfig": {
"linuxFxVersion": "Python|3.9",
"alwaysOn": true,
"pythonVersion": "3.9",
"appSettings": "[parameters('Appsettings_For_Fun_App')]"
but you can also do it via:
transform in the template, simplest to illustrate using a variable:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"myValues": {
"type": "object",
"defaultValue": {
"setting1": "value1",
"setting2": "value2",
"setting3": "value3"
}
}
},
"variables": {
"copy": [
{
"name": "foo",
"count": "[length(items(parameters('myValues')))]",
"input": {
"name": "[items(parameters('myValues'))[copyIndex('foo')].key]",
"value": "[items(parameters('myValues'))[copyIndex('foo')].value]"
}
}
]
},
"resources": [],
"outputs": {
"bar": {
"type": "array",
"value": "[variables('foo')]"
}
}
}

Editing json content with azure logic app

I want to create a logic app which replaces the value of resourcename inside an alert json structure received by a logic app. The alarm structure is as follows:
{
"schemaId": "AzureMonitorMetricAlert",
"data": {
"version": "2.0",
"properties": null,
"status": "Deactivated",
"context": {
"timestamp": "2021-08-21T01:43:09.2000007Z",
"id": "/subscriptions/<subscription_id>/resourceGroups/<my_resource_group>/providers/microsoft.insights/metricAlerts/teste%20-%20vpnp2s%20count",
"name": "teste - vpnp2s count",
"description": "",
"conditionType": "SingleResourceMultipleMetricCriteria",
"severity": "3",
"condition": {
"windowSize": "PT1M",
"allOf": [
{
"metricName": "P2SConnectionCount",
"metricNamespace": "Microsoft.Network/p2sVpnGateways",
"operator": "GreaterThanOrEqual",
"threshold": "1",
"timeAggregation": "Total",
"dimensions": [],
"metricValue": 0,
"webTestName": null
}
]
},
"subscriptionId": "<subscription_id>",
"resourceGroupName": "<my_resource_group>",
"resourceName": "some_resource_name",
"resourceType": "Microsoft.Network/p2sVpnGateways",
"resourceId": "/subscriptions/<subscription_id>/resourceGroups/<my_resource_group>/providers/Microsoft.Network/p2sVpnGateways/<p2svpngatewayid>",
"portalLink": "https://portal.azure.com/#resource/subscriptions/<subscription_id>/resourceGroups/<my_resource_group>/providers/Microsoft.Network/p2sVpnGateways/<theresourceid>"
}
}
}
I've been trying all sorts of mix with 'set variable', 'initialize variable', 'compose' blocks, but still no luck. Anyone has a clue?
Based on the above requirement i have created the logic app which replaces the resource name using HTTP request & replace actions.
Below is the code view of my logic app :
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"ConversionToString": {
"inputs": {
"variables": [
{
"name": "StringConversion",
"type": "string",
"value": "#{json(string(triggerBody()))}"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"FInalJsonOutput": {
"inputs": {
"variables": [
{
"name": "JsonOutput",
"type": "object",
"value": "#json(variables('replaceResouceName'))"
}
]
},
"runAfter": {
"ReplaceResourceName": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"ReplaceResourceName": {
"inputs": {
"variables": [
{
"name": "replaceResouceName",
"type": "string",
"value": "#{replace(variables('StringConversion'),'some_resource_name','newresource')}"
}
]
},
"runAfter": {
"ConversionToString": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {
"properties": {
"data": {
"properties": {
"context": {
"properties": {
"condition": {
"properties": {
"allOf": {
"items": {
"properties": {
"dimensions": {
"type": "array"
},
"metricName": {
"type": "string"
},
"metricNamespace": {
"type": "string"
},
"metricValue": {
"type": "integer"
},
"operator": {
"type": "string"
},
"threshold": {
"type": "string"
},
"timeAggregation": {
"type": "string"
},
"webTestName": {}
},
"required": [
"metricName",
"metricNamespace",
"operator",
"threshold",
"timeAggregation",
"dimensions",
"metricValue",
"webTestName"
],
"type": "object"
},
"type": "array"
},
"windowSize": {
"type": "string"
}
},
"type": "object"
},
"conditionType": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"portalLink": {
"type": "string"
},
"resourceGroupName": {
"type": "string"
},
"resourceId": {
"type": "string"
},
"resourceName": {
"type": "string"
},
"resourceType": {
"type": "string"
},
"severity": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
}
},
"type": "object"
},
"properties": {},
"status": {
"type": "string"
},
"version": {
"type": "string"
}
},
"type": "object"
},
"schemaId": {
"type": "string"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
Here is the sample output for reference post running the above logic app

Create Storage Service Encryption ARM template with Customer managed key

We're trying to create an ARM template which will allow us to specify our own encryption key. I have the script below, this encrypts the storage account, however this doesn't allow us to add our own key.
Is there a way to add it programatically, I know it can be done using the portal.
The script I have is
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageNamePrefix": {
"type": "string",
"metadata": {
"description": "The prefix string to add to a generated name."
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS"
],
"metadata": {
"description": "Storage Account type."
}
},
"blobEncryptionEnabled": {
"type": "bool",
"defaultValue": true,
"allowedValues": [
true,
false
],
"metadata": {
"description": "Enable or disable Blob encryption."
}
}
},
"variables": {
"storageAccountName": "[tolower( concat( parameters('storageNamePrefix'), uniqueString(subscription().id, resourceGroup().id) ))]",
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2016-01-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"kind": "Storage",
"properties": {
"encryption": {
"keySource": "Microsoft.Storage",
"services": {
"blob": {
"enabled": "[parameters('blobEncryptionEnabled')]"
}
}
}
}
}
],
"outputs": {
"storageAccountName": {
"type": "string",
"value": "[variables('storageAccountName')]"
}
}
}
I've seen this on Azure Quickstart Templates, which seems to have the title of what I need, but I can't see where or how to add the key I would like to use..
{
"$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_RAGRS",
"Standard_ZRS",
"Premium_LRS"
],
"metadata": {
"description": "Storage Account type."
}
},
"blobEncryptionEnabled": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Enable or disable Blob encryption at Rest."
}
}
},
"variables": {
"storageAccountName": "[tolower( concat('sawithsse', substring(parameters('storageAccountType'), 0, 2), uniqueString(subscription().id, resourceGroup().id) ))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2016-12-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"kind": "Storage",
"properties": {
"encryption": {
"keySource": "Microsoft.Storage",
"services": {
"blob": {
"enabled": "[parameters('blobEncryptionEnabled')]"
}
}
}
}
}
],
"outputs": {
"storageAccountName": {
"type": "string",
"value": "[variables('storageAccountName')]"
}
}
}
The portal way of enabling customer key for encryption is outlined in the below link:
https://learn.microsoft.com/en-us/azure/storage/common/storage-service-encryption-customer-managed-keys
This link mentions the ability to use Powershell, but I can't find any reference for it.
Hope this makes sense.
Thanks in advance.. :)
Something like this:
"properties": {
"encryption": {
"keySource": "Microsoft.Keyvault",
"keyvaultproperties": {
"keyname": xxx,
"keyvaulturi": xxx,
"keyversion": xxx
}
}
}
Source: https://learn.microsoft.com/en-us/rest/api/storagerp/storageaccounts/create#keyvaultproperties
another way, do it with powershell, add -debug and capture the rest call, port it to template.

Azure ARM Template add second disk

I would like to add in my template option for second disk based from "userImageStorageAccountName" My template was wrking until ii try to add second disk then when I try to deploy Vm i receive:
Blockquote {"code":"StorageAccountAlreadyExists","message":"The storage account named TEST already exists under the subscription."}}
But my target is to create in that storage account i don't want to create new storage account
BTW do you have maybe a nice documentation to create template for dummies :D
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "0.0.4.0",
"parameters": {
"VM_name": {
"type": "string",
"minLength": 11,
"maxLength": 12,
"defaultValue": "testxxx0021",
"metadata": {
"description": "Hostnem+dns name"
}
},
"VM_Class": {
"type": "string",
"allowedValues": [
"Standard_A1",
"Standard_A2",
"Standard_A3"
],
"defaultValue": "Standard_A2",
"metadata": {
"description": "type VM"
}
},
"sizeOfEachDataDiskInGB": {
"type": "string",
"defaultValue": "20",
"metadata": {
"description": "Size of each data disk in GB"
}
},
"userImageStorageAccountName": {
"type": "string",
"defaultValue": "TEST",
"metadata": {
"description": "Storage account for machine"
}
},
"Windows_template": {
"type": "string",
"allowedValues": [
"https://TEST.blob.core.windows.net/system/Microsoft.Compute/Images/xxxxxxxx/template-dddosDisk.vhd",
"https://TEST.blob.core.windows.net/testtemp/xxxxxxx.vhd",
"https://TEST.blob.core.windows.net/testtemp/template-xxxxx.vhd"
],
"defaultValue": "https://TEST.blob.core.windows.net/TESTtemp/template-xxxxxxxxx.vhd",
"metadata": {
"description": "Uri of the your user image"
}
},
"adminUserName": {
"type": "securestring",
"defaultValue": "testadmin",
"metadata": {
"description": "UserName for the Virtual Machine"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Password for the Virtual Machine"
}
},
"osType": {
"type": "string",
"allowedValues": [
"Windows",
"Linux"
],
"defaultValue": "Windows",
"metadata": {
"description": "This is the OS that your VM will be running"
}
}
},
"variables": {
"location": "[resourceGroup().location]",
"vmName": "[parameters('VM_name')]",
"virtualNetworkName": "xx.xxx.xxx.0-xx-vnet",
"nicName": "[parameters('VM_name')]",
"addressPrefix": "xx.xxx.xxx.0/22",
"subnet1Name": "xx.xxx.xxx.0-xx-vnet",
"subnet1Prefix": "xx.xxx.xxx.0/24",
"vmStorageAccountContainerName": "vhds",
"storageAccountType": "Standard_LRS",
"storageAccountName": "[parameters('userImageStorageAccountName')]",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
"subnet1Ref": "[concat(variables('vnetID'),'/subnets/',variables('subnet1Name'))]",
"osDiskVhdName": "[concat('http://',parameters('userImageStorageAccountName'),'.blob.core.windows.net/vhds/',variables('vmName'),'osDisk.vhd')]",
"apiVersion": "2015-06-15",
"dataDisk1VhdName": "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('vmName'),'dataDisk1.vhd')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "[variables('apiVersion')]",
"location": "[variables('location')]",
"properties": {
"accountType": "[variables('storageAccountType')]"
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/virtualNetworks",
"name": "[variables('virtualNetworkName')]",
"location": "[variables('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnet1Name')]",
"properties": {
"addressPrefix": "[variables('subnet1Prefix')]"
}
}
]
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/networkInterfaces",
"name": "[variables('nicName')]",
"location": "[variables('location')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnet1Ref')]"
}
}
}
]
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Compute/virtualMachines",
"name": "[variables('vmName')]",
"location": "[variables('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('VM_Class')]"
},
"osProfile": {
"computerName": "[variables('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"osDisk": {
"name": "[concat(variables('vmName'),'-osDisk')]",
"osType": "[parameters('osType')]",
"caching": "ReadWrite",
"createOption": "FromImage",
"image": {
"uri": "[parameters('Windows_template')]"
},
"vhd": {
"uri": "[variables('osDiskVhdName')]"
}
}
},
"dataDisks": [
{
"name": "datadisk1",
"diskSizeGB": "[parameters('sizeOfEachDataDiskInGB')]",
"lun": 0,
"vhd": {
"Uri": "[variables('dataDisk1VhdName')]"
},
"createOption": "Empty"
}
],
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": "true",
"storageUri": "[concat('http://',parameters('userImageStorageAccountName'),'.blob.core.windows.net')]"
}
}
}
}
]
}
thx for Help
Looking over the JSON, you are requesting platform to ask user to provide a new storage account. To use exiting storage account you can refer existing parameter to you have already provided .
Original JSON :
"dataDisk1VhdName": "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('vmName'),'dataDisk1.vhd')]"
Suggested JSON
"dataDisk1VhdName": "[concat('http://',parameters('userImageStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('vmName'),'dataDisk1.vhd')]"
Hope this helps.
Check if the storage account tags have been changed through the Azure/PowerShell portal by somebody else, and are different than the ones specified on the ARM template.
Sounds like a bug on the ARM deployment system, tags should be able to be updated but it is currently failing for storage account resources.
For more info see http://davidjrh.intelequia.com/2016/07/the-storage-account-already-exists.html