I'm working on ARM Templates. Actually, I have to deploy two resources at a time into my Azure account. For that, I used copyindex() concept with the help of following document and am able to deploy them successfully. Now am trying to display the names of deployed resources by using Output concept in ARM. But due to looping of resources deployment, its resulting in following error.
"DeploymentOutputEvaluationFailed",
"message": "Unable to evaluate template outputs: 'alertName'. Please see error details and deployment operations. Please see https://aka.ms/arm-debug for usage details.",
"details": [
{
"code": "DeploymentOutputEvaluationFailed",
"target": "alertName",
"message": "The template output 'alertName' is not valid: The language expression property 'alertMetricType' can't be evaluated.."
}
]
Could you please suggest me to "How to fetch the values of copyindex() looping as ARM Output session values"
I would suggest to reference it like this for example because you need to assemble anarray which you need to each of your template to take the output from the previous one and concat it with its own output then print the result.
"parameters": {
"state": {
"value": []
}
}
"parameters": {
"state": {
"value": "[reference(concat('loop', copyIndex())).outputs.state.value]"
}
}
then call it in output:
"outputs": {
"state": {
"type": "array",
"value": "[concat(parameters('state'), array(stuff_out))]"
}
Related
Trying to assign permissions for the app service deployment slot to keyvault and having a hell of a time getting it
{
"tenantId": "[subscription().tenantId]",
"objectId": "[resourceId('Microsoft.Web/sites/slots', parameters('azureAppService').webSiteName, 'DEV').identity.principalId]",
"permissions": {
"secrets": [
"Get"
]
}
}
Not sure what I'm doing wrong here, the template validation goes through, but upon deployment but I get an error. How do I specify the resource ID for the deployment slot?
Here is the error
{
"status": "Failed",
"error": {
"code": "InvalidTemplate",
"message": "Unable to process template language expressions for resource '/subscriptions/---/resourceGroups/Test/providers/Microsoft.KeyVault/vaults/KEYVAULT-TEST' at line '447' and column '9'. 'The language expression property 'identity' can't be evaluated.'",
"additionalInfo": [
{
"type": "TemplateViolation",
"info": {
"lineNumber": 447,
"linePosition": 9,
"path": ""
}
}
]
}
}
You would need to use the reference function (see documentation):
[reference(resourceId('Microsoft.Web/sites/slots', parameters('azureAppService').webSiteName, 'DEV'), '2022-03-01', 'full').identity.principalId]
"[reference(resourceId('Microsoft.Web/sites/slots', parameters('azureAppService').webSiteName, 'DEV'), '2020-06-01', 'full').identity.principalId]",
So it seems that even tho I added this to the deployment slots
"identity": {
"type": "SystemAssigned"
},
It wasn't creating the systemassigned identity. Once I manually created it and then redeployed the ARM template, it worked.
I have a misunderstanding how blueprint outputs works and how to properly import values from one artifact to another.
Let me describe my attempts to get variable from artifact:
I have created two artifacts inside resource groups:
I have tried to transfer variables like vnet_name, vnet_addresses from VNET artifact to SUBNET_AKS artifact using the following syntax:
VNET:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
........
"outputs": {
"vnet_name_output": {
"type": "string",
"value": "[variables('vnet_name')]"
},
"vnet_ip_range_output": {
"type": "string",
"value": "[parameters('vnet_ip_range')]"
},
"vnet_path_output": {
"type": "string",
"value": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnet_name'))]"
}
}
}
Next step was to add output variable to SUBNET_AKS artifacts:
"resources": [
{
"apiVersion": "2018-04-01",
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(artifacts('VNET').outputs.vnet_name_output, '/', concat(parameters('deployment_prefix'),'-aks-subnet'))]",
But the following error appears:
Deployment template validation failed: 'The template resource '[concat(artifacts('VNET').outputs.vnet_name_output, '/', concat(parameters('deployment_prefix'),'-aks-subnet'))]' at line '27' and column '9' is not valid: The template function 'artifacts' is not valid. Please see https://aka.ms/arm-template-expressions for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'.
How can I understand how outputs parameters should properly work in Azure Blueprint definition?
Azure Blueprint is just an orchestration layer responsible for the ordering and deployment of artifact(s). ARM templates are one of three valid types - policyAssignment and roleAssignment are the other two.
This means you have two "template" artifacts: VNET and SUBNET_AKS. Each one should be treated like an actor / black-box, meaning you can only use functions available to ARM templates. If you need a parameter from the Blueprint it must come in as a parameter.
That is why you are getting that particular syntax error. The artifacts() function is only available to Blueprints.
Instead, you need to update your ARM template so that it specifies a named output value. In your Azure Blueprint, you can reference the output of a prior artifact as an input parameter to a subsequent Blueprint artifact.
Hopefully these code snippets and docs can point you in the right direction.
When I try to use an ARM linked Template like...
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "[concat('EventHubLinkedTemplate-', parameters('eventHubNames')[copyindex('eventHubNameIterator')])]",
"copy": {
"name": "eventHubNameIterator",
"count": "[length(parameters('eventHubNames'))]"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[uri(deployment().properties.templateLink.uri, '/eventHub/template.json')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"consumerGroups": "[parameters('consumerGroups')]",
"eventHubName": "[concat(variables('eventHubNamespace'), '/', parameters('eventHubNames'))]"
}
}
}
... from parent ARM template, using deploy option of Visual Studio 2019 ARM project, the deployment fails within the next message:
07:48:12 - Resource Microsoft.Resources/deployments 'EventHubLinkedTemplate-test' failed with message '{
"error": {
"code": "InvalidTemplate",
"message": "Unable to process template language expressions for resource '/subscriptions/********-****-****-****-************/resourceGroups/*****/providers/Microsoft.Resources/deployments/EventHubLinkedTemplate-test' at line '127' and column '9'. 'The language expression property 'templateLink' doesn't exist, available properties are 'template, templateHash, parameters, mode, provisioningState'.'",
"additionalInfo": [
{
"type": "TemplateViolation",
"info": {
"lineNumber": 127,
"positionNumber": 9,
"snippet": ""
}
}
]
}
}'
Does anyone knows any way to use [deployment().properties.templateLink.uri] on local deployments through ARM templates?
As far as I can found on the documentation, seems it is not supported yet...
https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md
https://github.com/MicrosoftDocs/azure-docs/issues/8748
No, it's impossible.
As the official article said:
The templateLink property is only returned when linking to a remote template with a URL. If you're using a local template, that property isn't available.
No, this is not possible, because for that to work you have to upload the template (else, how you would get a link??).
A simple workaround would be to have a powershell script that uploads everything and starts the deployment. Using Visual Studio for ARM Template development is not the best experience anyway.
I'm trying to deploy a Virtual network using ARM template with multiple subnets. I have a linked template which creates NSGs,route table and assigns it to a specific subnet. I'm using copy to create multiple subnets. Route table should be assigned to only one particular subnet. I control this using If condition. The issue here is i'm not able to use the linked template output in the If condition. It fails with below error.
'{
"error": {
"code": "InvalidTemplate",
"message": "Unable to process template language expressions for resource
'/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/' at line '143' and column '9'. 'The provided
arguments for template language function 'if' is not valid: all arguments should be of type 'boolean'. Please see https://aka.ms/arm-template-expressions#if for usage details.'"
}
}'
Main Template (Subnet Creation snippet):-
"copy": [
{
"name": "subnets",
"count": "[length(parameters('subnetList'))]",
"input": {
"name": "[parameters('subnetList')[copyIndex('subnets')].name]",
"properties": {
"addressPrefix": "[parameters('subnetList')[copyIndex('subnets')].addressprefix]",
"networkSecurityGroup": "[if(equals(parameters('subnetList')[copyIndex('subnets')].name, 'GatewaySubnet'), json('null'), variables('nsgId'))]",
"routeTable": "[if(bool(parameters('subnetList')[copyIndex('subnets')].useRouteTable), reference('routeTableDeployment').outputs.resourceID.value, json('null'))]"
}
}
}
]
Route Table (Output snippet):-
"outputs": {
"resourceID": {
"type": "object",
"value": {
"id": "[resourceId('Microsoft.Network/routeTables', variables('routeTableName')]"
}
}
}
It works if I define a variable and pass it to if condition similar to nsg as below:-
"routeTableId": {
"id": "[resourceId('Microsoft.Network/routeTables', 'routeTableName')]"
}
"routeTable": "[if(bool(parameters('subnetList')[copyIndex('subnets')].useRouteTable), variables('routeTableId'), json('null'))]"
I'm using the following piece of code in my ARM template parameters file to retrieve the secret value from keyvault:
"parameters": {
"mailAccount": {
"reference": {
"keyVault": {
"id": "/subscriptions/GUID/resourceGroups/KeyVaultRG/providers/Microsoft.KeyVault/vaults/KeyVault"
},
"secretName": "mailAccount"
}
},
and in the template file:
"appSettings": [
{
"name": "mailAccount",
"value": "[parameters('mailAccount')]"
},
{
I'd like to know if it is possible to reference a KeyVault by its name using dynamically constructed object (i.e. not /subscriptions/GUID/resourceGroups/KeyVaultRG/providers/Microsoft.KeyVault/vaults/KeyVault but [resourceId(subscription().subscriptionId, resourcegroup().name, 'Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]) or [resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))] ?
In fact, the main objective is to be able to pass the different KeyVault names when deploying templates - where the similar values are stored.
The need to have several KeyVaults is justified by the resources (and cost) separation.
Now I see only validation errors saying ~ resourceId function cannot be used while referencing parameters.
I cannot use nested\linked templates (and output values).
What I am usually doing to avoid this limitation of the resourceId function is to define a variable with the value of the parameter, then using the variable instead in the resourceId function.
Example:
"parameters": {
"KeyVaultName": {
"type": "string",
"metadata": {
"description": "Key Vault Name"
}
}
},
"variables": {
"KeyVaultName": "[parameters('KeyVaultName')]"
}
Then when I am referencing the KeyVault resource I reference it using the variable like this:
"[resourceId('Microsoft.KeyVault/vaults', variables('KeyVaultName')]"