Arm Template conditional output parameters Arm Template conditional output parameters azure azure

Arm Template conditional output parameters


There is a trick to solve this issue and we use it successfully.

Let's see for example how the following template returns a value only if the corresponding resource has been deployed.

"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",  "contentVersion": "1.0.0.0",  "parameters": {    "appInsightsLocation": {      "type": "string",      "defaultValue": "",      "allowedValues": [        "",        "northeurope",        "westeurope"      ]    }  },  "variables": {    "appInsightsName": "exampleAppInsights",    "planName": "example-plan",    "appInsightsEnabled": "[if(greater(length(parameters('appInsightsLocation')), 0), 'true', 'false')]",    "appInsightsOrPlanResource": "[if(bool(variables('appInsightsEnabled')), concat('Microsoft.Insights/components/', variables('appInsightsName')), concat('Microsoft.Web/serverFarms/', variables('planName')))]",    "appInsightsKeyOrPlanName": "[if(bool(variables('appInsightsEnabled')), 'InstrumentationKey', 'name')]"  },  "resources": [    {      "comments": "The example service plan",      "apiVersion": "2015-08-01",      "type": "Microsoft.Web/serverfarms",      "location": "[resourceGroup().location]",      "name": "[variables('planName')]",      "sku": {        "name": "B1",        "capacity": 1      },      "properties": {        "numberOfWorkers": 1,        "name": "[variables('planName')]"      }    },    {      "comments": "The application insights instance",      "apiVersion": "2014-04-01",      "condition": "[bool(variables('appInsightsEnabled'))]",      "type": "Microsoft.Insights/components",      "location": "[parameters('appInsightsLocation')]",      "name": "[variables('appInsightsName')]",      "properties": {}    }  ],  "outputs": {    "appInsightsKey": {      "value": "[if(bool(variables('appInsightsEnabled')), reference(variables('appInsightsOrPlanResource'))[variables('appInsightsKeyOrPlanName')], '')]",      "type": "string"    }  }

The template declares two resources. One app service plan and one Application Insights instance. The AppInsights instance is deployed only if the location parameter is not empty string. So the instrumentation key of this instance is also returned only if it has been created.

To achieve this we also need a resource that is always present. In our case this is the service plan. We use this resource to get the reference when AppInsights is not deployed. This could be any azure resource of course.

The trick happens on the two variables appInsightsOrPlanResource and appInsightsKeyOrPlanName we declare. When appInsightsLocation is provided then those two variables end up referencing the key of the instance which is returned from the output.

When appInsightsLocation is not provided on the other hand those two variables contain a valid reference to the service plan that is not used but it's valid. We need to do this one because if function evaluates always both sides. An empty string is returned from the output in this case though.


I know this is an old question, but in case anyone arrives here, it looks like MSFT has fixed this in two ways now.

In Feb 2019 they fixed the 'if' evaluation to only evaluate the true side.
https://feedback.azure.com/forums/281804-azure-resource-manager/suggestions/31538470-arm-template-if-function-should-not-evaluate-both

In August 2019 they added support for condition: in the outputs.https://feedback.azure.com/forums/281804-azure-resource-manager/suggestions/19492006-conditional-output-from-arm-template

https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authoring-templates#outputs

Looks like as long as you're at Azure CLI version 2.0.72 you'll have access to these changes. I just tested both on 2.0.76 and they appear to work.