Fast question. How create installation using templates? Can you give an example? How construct 'InstallationTemplate' object.
When you want to create an ARM template based on the json schema of Microsoft.NotificationHubs:
Create a new project in Visual Studio 2015.
Choose for a Cloud project
Choose for Azure Resource Group
Choose Blank Template
Open azuredeploy.json
You will see this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"variables": {
},
"resources": [
],
"outputs": {
}
}
Then begin with the resources part by typing apiVersion (note that you get intellisense already):
"resources": [
{
"apiVersion": ""
}
],
After this add the type: Just select the correct value.
After the type is set. You will get intellisense on the allowed properties.
There are more parameters available. But when using the main properties and
create parameters of the hardcoded values and at the end you will get a template like:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceLocation": {
"type": "string"
},
"namespaceName": {
"type": "string"
},
"notificationHubName": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"apiVersion": "2014-09-01",
"name": "[parameters('namespaceName')]",
"type": "Microsoft.NotificationHubs/namespaces",
"location": "[parameters('namespaceLocation')]",
"properties": {
"name": "[parameters('namespaceName')]",
"namespaceType": "NotificationHub"
},
"resources": [
{
"apiVersion": "2014-09-01",
"name": "[parameters('notificationHubName')]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"location": "[parameters('namespaceLocation')]",
"dependsOn": [
"[concat('Microsoft.NotificationHubs/namespaces/', parameters('namespaceName'))]"
],
"properties": {
"name": "[parameters('notificationHubName')]"
}
}
]
}
],
"outputs": {
}
}
Related
how to execute ARM template whenever System Managed Identity is turned on VMSS (Virtual Machine Scale Set).
You can use the below template for your requirement:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"virtualMachineScaleSetName": {
"type": "String"
}
},
"variables": {
"virtualMachineScaleSetApiVersion": "2021-04-01"
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"apiVersion": "[variables('virtualMachineScaleSetApiVersion')]",
"name": "[parameters('virtualMachineScaleSetName')]",
"location": "[parameters('location')]",
"identity": {
"type" : "SystemAssigned"
}
}
]
}
Existing VMSS:
Running the Template:
Output:
I am creating ARM template for Route table creation. A simple ARM template downloaded from the template deployment is failing. After I run the ARM template, it asks for the name and throws the below error.
I have tried giving names like routeVnet, vnetroute etc.
Saw some posts where giving the combination of lowercase uppercase in name will fix the issue. But it doesn't work here.
The arm template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.5",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"tagsByResource": {
"type": "object",
"defaultValue": {},
"metadata": {
"description": "Optional tags provided by the user via createUiDefinition.json"
}
},
"disableBgpRoutePropagation": {
"type": "bool"
}
},
"variables": {},
"resources": [
{
"apiVersion": "2019-02-01",
"type": "Microsoft.Network/routeTables",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"tags": "[ if(contains(parameters('tagsByResource'), 'Microsoft.Network/routeTables'), parameters('tagsByResource')['Microsoft.Network/routeTables'], json('{}')) ]",
"properties": {
"disableBgpRoutePropagation": "[parameters('disableBgpRoutePropagation')]"
}
}
],
"outputs": {}
}
The parameter template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "eastus"
},
"Name": {
"value": ""
},
"tagsByResource": {
"value": {}
},
"disableBgpRoutePropagation": {
"value": true
}
}
}
The problem is with your parameter file where you are passing parameter name as "Name", in template your parameter is name while in parameter file you have mentioned it as Name.
The correct parameter file will look like:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "eastus"
},
"name": {
"value": "routeVnet12"
},
"tagsByResource": {
"value": {}
},
"disableBgpRoutePropagation": {
"value": true
}
}
}
We want to have two resource group, 1- shared-resource group for shared resources like app service plan, ...
2- another resource-group for other resources like web-app.
We are using nested link template which contains three level:
highest level is main deployment template file which contains everything.
next level is for calling all resource templates for each resource-group, e.g we have two template file in this level one for shared resource-group and two other resource-group, so for-example first file will call some link template to create app service plan, elastic pool and ....
second file will call link templates for deploying web-app, network and ....
last level is our generic resource templates, in this level for each resource we have a template file e.g for web-app we have a generic template which deploy web-app with some parameters.
Now the question is how we can use 'dependson' to create all shared-Resources first after that deploy all other resources?
*please note: shared resources are in different resource-group and other resources are in another resource-group so we have two resource-group which both and all included resources are deploying in main template file.
My main deployment template file is this:
// Include rg-CockpitShared and app specific resources - and share parameters
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-
01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"cockpitEnvironment": {
"type": "string"
}
},
"variables": {
"currentTemplateUri": "[deployment().properties.templateLink.uri]",
"rgCockpitSharedUrl": "[concat(uri(variables('currentTemplateUri'), 'rg-CockpitShared/rg-CockpitShared.json'))]",
"rgCockpitSharedParametersUrl": "[concat(uri(variables('currentTemplateUri'), concat('rg-CockpitShared/rg-CockpitShared.parameters.', parameters('cockpitEnvironment'), '.json')))]",
"rgClientCmdbTemplateUrl": "[concat(uri(variables('currentTemplateUri'), 'rg-ClientCmdb/rg-ClientCmdb.json'))]",
"rgClientCmdbParametersUrl": "[concat(uri(variables('currentTemplateUri'), concat('rg-ClientCmdb/rg-ClientCmdb.parameters.', parameters('cockpitEnvironment'), '.json')))]"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"location": "[parameters('location')]",
"apiVersion": "2019-10-01",
"name": "CockpitShared",
"tags": {
"devOwner": "aspBuild"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('rgCockpitSharedUrl')]",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"uri": "[variables('rgCockpitSharedParametersUrl')]",
"contentVersion": "1.0.0.0"
}
}
},
{
"type": "Microsoft.Resources/deployments",
"location": "[parameters('location')]",
"apiVersion": "2019-10-01",
"name": "otherResources",
"tags": {
"devOwner": "aspBuild"
},
"dependsOn": [
"CockpitShared"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('rgClientCmdbTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"uri": "[variables('rgClientCmdbParametersUrl')]",
"contentVersion": "1.0.0.0"
}
}
}
],
"outputs": {
"rgCockpitSharedUrl": {
"type": "string",
"value": "[variables('rgCockpitSharedUrl')]"
},
"rgCockpitSharedParametersUrl": {
"type": "string",
"value": "[variables('rgCockpitSharedParametersUrl')]"
}
}
}
So What I have done here is using dependsOn = "CockpitShared" and expected that first it deploys shared resources and after that start to deploy 'otherResources', but I got error that app-service-plan is not found which means it's not wait to shared resources be deployed and I don't understand why? :(
Finally I found a solution:
I used 'reference' instead of 'dependson'.
So in my shared-Resources arm template I return app service plan name as output and used it from my main deployment file so it wait for finishing shared resources deployment first and after that start to deploy web app ...
for more detail see below code:
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"cockpitEnvironment": {
"type": "string"
},
"storageAccountUri": {
"type": "string"
}
},
"variables": {
"rgCockpitSharedUrl": "[concat(uri(parameters('storageAccountUri'), 'rg-CockpitShared/rg-CockpitShared.json'))]",
"rgClientCmdbTemplateUrl": "[concat(uri(parameters('storageAccountUri'), 'ClientCmdb/rg-ClientCmdb/rg-ClientCmdb.json'))]"
},
"functions": [
{
"namespace": "ClientCmdb",
"members": {
"SelectValueByEnv": {
"parameters": [
{
"name": "Environment",
"type": "string"
},
{
"name": "prodValue",
"type": "string"
},
{
"name": "devValue",
"type": "string"
},
{
"name": "testValue",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[if(equals(parameters('Environment'),'prod'),parameters('prodValue'),if(equals(parameters('Environment'),'dev'),parameters('devValue'),parameters('testValue')))]"
}
}
}
}
],
"resources": [
{
"type": "Microsoft.Resources/deployments",
"location": "[parameters('location')]",
"apiVersion": "2019-10-01",
"name": "CockpitShared",
"tags": {
"devOwner": "aspBuild"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('rgCockpitSharedUrl')]"
},
"parameters": {
"rgName": {
"value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'rg-CockpitShared','rg-CockpitShared','rg-CockpitShared')]"
},
"location": {
"value": "[parameters('location')]"
},
"cockpitEnvironment": {
"value": "[parameters('cockpitEnvironment')]"
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"location": "[parameters('location')]",
"apiVersion": "2019-10-01",
"name": "ClientCmdb",
"tags": {
"devOwner": "aspBuild"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('rgClientCmdbTemplateUrl')]"
},
"parameters": {
"rgName": {
"value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'rg-ClientCmdb','rg-ClientCmdb','rg-ClientCmdb')]"
},
"location": {
"value": "[ClientCmdb.SelectValueByEnv(parameters('cockpitEnvironment'),'northeurope','northeurope','northeurope')]"
},
"cockpitEnvironment": {
"value": "[parameters('cockpitEnvironment')]"
},
"planName": {
// Here__________________________________________________________________________________
"value": "[reference('CockpitShared').outputs.planName.value]"
}
}
}
}
],
}
so basically I pass my app service plan name from shared resource template to main template and main template gets it by 'reference' and pass it to other resources template via parameter.
Regarding to do that I had to use inline params as I was using params in seperated files...
Hope it's useful for someone else :)
Is it possible to get the ARM template as it was during runtime in the Azure Portal with the variables and parameters resolved?
Example below:
AzureDeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"defaultValue": "dev",
},
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
]
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"variables": {
"storageAccountName": "[concat('companyname',parameters('environment'),'sa01'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[variables('storageName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageSKU')]"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
]
}
AzureDeploy.parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"value": "dev"
}
}
}
If this deployment was to fail on something such as the name or the SKU, would I be able to access the portal or somehow see how these values were resolved when the script was ran?
The deployment happens in a CD pipeline in AzureDevops and I have control of the variable groups etc. so I know what is being passed in but not how it resolves. In a more complex template, I have an error claiming an Id is not set on a Logic App API connection but I cannot tell if the error is due to the variable I am using in the concat function or if the value is genuinely incorrect (resolving okay according to data passed in).
If anyone is familiar with troubleshooting these through the deployments blade in Azure then you may have some tips on how to see a more detailed view.
Thanks,
Edit:
The code below triggers Intellisense in Visual Studio 2019 but has been confirmed working during deployment. No warnings in VS Code as per comments. Majority of code omitted for brevity.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"defaultValue": "dev"
},
"increment": {
"type": "string",
"defaultValue": "01"
},
"keyvaultName": {
"type": "string",
"defaultValue": "randomKeyVaultName",
"metadata": {
"description": "Keyvault Name for deployment"
}
}
},
"variables": {
"uniqueKeyVaultName": "[parameters('keyvaultName')]"
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2016-10-01",
"name": "[concat(variables('uniqueKeyVaultName'), '/407045A0-1B78-47B5-9090-59C0AE9A96F6')]",
"location": "northeurope",
"dependsOn": [
"[resourceId('Microsoft.Resources/deployments', 'cosmosdb_linkedtemplate')]"
],
"properties": {
"contentType": "Graph",
"value": "[concat('{''D'': ''DatabaseName'', ''U'': ''https://randomcosmosdb-',parameters('environment'),'-cdb-',parameters('increment'),'.documents.azure.com'', ''C'': ''CollectionName'', ''K'': ''',reference('cosmosdb_linkedtemplate').outputs.accountKey.value,'''}')]",
"attributes": {
"enabled": true
}
}
}
],
"outputs": {}
}
If you want to see the evaluated template there are a few things you can do to get it without deploying:
1) call the /validate api: https://learn.microsoft.com/en-us/rest/api/resources/deployments/validate -- but you need to use an older apiVersion at the moment (e.g. 2017-05-01)... the response will contain the fully evaluated template. If you have an older version of PowerShell or the CLI, you can see the response from the rest API by using the -debug switch. But keep in mind, the more recent versions of PS/CLI will use a newer apiVersion and those don't return the full template (at this time).
2) The /whatif api will also return evaluated JSON but there's a bit more to wade through if all you're after is the evaluated template: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-deploy-what-if
Tha help?
I have trying to set up the access keys to an azure service bus in an azure resource manager template. No matter what I do the template ignores the keys and sets some random ones instead without giving any errors. I have the following parameters file:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": { "value": "Integration" },
"primaryKey": {
"value": "<myKey1>"
},
"secondaryKey": {
"value": "<myKey2>"
}
}
}
where myKey are substitued the real value of the keys. I also have the following template (part of it below):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": {
"type": "string"
},
"primaryKey": {
"type": "string"
},
"secondaryKey": {
"type": "string"
}
},
"variables": {
"ServiceBus_ReadWriteKey": "[concat(parameters('environmentName'), '/ReadWrite')]",
"servicebus_namespace": "[parameters('environmentName')]",
"servicebus_topic_name": "[concat(parameters('environmentName'), '/products')]",
This is the resource that creates the access policy and should set it's keys:
{
"type": "Microsoft.ServiceBus/namespaces/AuthorizationRules",
"name": "[variables('ServiceBus_ReadWriteKey')]",
"apiVersion": "2015-08-01",
"scale": null,
"properties": {
"keyName": "ReadWrite",
"claimType": "SharedAccessKey",
"claimValue": "None",
"primaryKey": "[parameters('primaryKey')]",
"secondaryKey": "[parameters('secondaryKey')]",
"rights": [
"Listen",
"Send"
],
"revision": -1
},
"dependsOn": [
"[resourceId('Microsoft.ServiceBus/namespaces', variables('servicebus_namespace'))]"
]
},
The access policy is created, always with a random key, never the one I specified. How do I set this programmatically and what is wrong with the code above?
You are using a different api version as the sample you are using:
sample api version 2014-09-01
your api version 2015-08-01
try to change the api version to see if that causes the issue