【问题标题】:Arm Template conditional output parametersArm 模板条件输出参数
【发布时间】:2017-08-31 11:06:43
【问题描述】:

我有一个有条件地创建资源的 ARM 模板:

    {
  "type": "Microsoft.Storage/storageAccounts",
  "sku": {
    "name": "Standard_GRS",
    "tier": "Standard"
  },
  "kind": "BlobStorage",
  "name": "[variables('storageAccounts_name')]",
  "condition": "[equals(parameters('is_Not_Development'), 'True')]",
  "apiVersion": "2017-06-01",
  "location": "[resourceGroup().location]",
  "scale": null,
  "properties": {
    "accessTier": "Hot"
  },
  "dependsOn": []
},

在我的输出参数中,如果未创建资源,则会导致错误:

    "storageAccountConnectionString": {
  "type": "string",
  "value": "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccounts_name'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccounts_name')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
},

我试过这个:

    "storageAccountConnectionString": {
  "type": "string",
  "condition": "[equals(parameters('is_Not_Development'), 'True')]",
  "value": "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccounts_name'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccounts_name')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
},

带有条件子句,但无法识别。如何使输出参数有条件?

更新:

我尝试了以下方法:

    "storageAccountConnectionString": {
  "type": "string",
  "value": "[if(equals(parameters('is_Not_Development'),'False'),'null',Concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccounts_name'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccounts_name')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value))]"
},

但它给了我同样的错误信息,它必须同时评估真假条件。

【问题讨论】:

标签: azure arm-template


【解决方案1】:

有一个技巧可以解决这个问题,我们成功使用了。

例如,让我们看看以下模板如何仅在已部署相应资源时才返回值。

"$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"
    }
  }

模板声明了两个资源。一个应用服务计划和一个 Application Insights 实例。仅当 location 参数不是空字符串时,才会部署 AppInsights 实例。所以这个实例的检测键也只有在它被创建后才会返回。

要实现这一点,我们还需要始终存在的资源。在我们的例子中,这是服务计划。我们使用此资源在未部署 AppInsights 时获取参考。当然,这可以是任何 azure 资源。

诀窍发生在我们声明的两个变量appInsightsOrPlanResource 和appInsightsKeyOrPlanName 上。当提供appInsightsLocation 时,这两个变量最终会引用从输出返回的实例的键。

另一方面,当未提供appInsightsLocation 时,这两个变量包含对未使用但有效的服务计划的有效引用。我们需要这样做,因为if 函数总是评估双方。但在这种情况下,输出会返回一个空字符串。

【讨论】:

  • 输出value 上的if 条件对我有用。当条件为真时,它返回资源信息。为 false 时,返回空字符串。
  • 这是一个很好的答案,但现在 arm 模板支持条件输出已经过时了。
【解决方案2】:

我知道这是一个老问题,但万一有人来到这里,看起来 MSFT 现在已经通过两种方式解决了这个问题。

在 2019 年 2 月,他们修复了“if”评估,只评估真实的一面。
https://feedback.azure.com/forums/281804-azure-resource-manager/suggestions/31538470-arm-template-if-function-should-not-evaluate-both

2019 年 8 月,他们在输出中添加了对 condition: 的支持。 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

看起来只要您使用的是 Azure CLI 2.0.72 版,您就可以访问这些更改。我刚刚在 2.0.76 上测试了两者,它们似乎都可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多