在嵌套模板中引用 listKeys()

Reference listKeys() in nested templates

我正在创建一个在不同资源组中部署大量资源的 ARM 模板。实际上,资源组本身就是部署的一部分。在简单版本中,我只创建两个资源组(masterRGdependentRG),然后创建两个嵌套(内联)部署。第一个内联部署将存储帐户 (testsadj1604) 放在 masterRG 中。此部署依赖于 masterRG。

第二个部署创建一个密钥库并尝试将来自 testsadj1604 的连接字符串存储在该库中。

在我的真实案例中,我有更多的资源组,我实际上尝试部署一个连接字符串为 'appsetting' 的函数应用程序。不过方法是一样的。

我得到的错误如下:

Deployment failed. Correlation ID: 9c359e8e-8657-4756-a5a3-f9c5698fbb46. {
  "error": {
    "code": "ResourceNotFound",
    "message": "The Resource 'Microsoft.Storage/storageAccounts/testsadj1604' under resource group '<null>' was not found."
  }
}

这是我的代码:

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2018-05-01",
      "name": "masterRG",
      "location": "West Europe",
      "properties": {}
    },
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2018-05-01",
      "name": "dependentRG",
      "location": "West Europe",
      "properties": {}
    },
    {
      "name": "masterRgDeployment",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "resourceGroup": "masterRG",
      "dependsOn": [
        "masterRG"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "apiVersion": "2019-06-01",
              "type": "Microsoft.Storage/storageAccounts",
              "name": "testsadj1604",
              "location": "West Europe",
              "sku": {
                "name": "Standard_GRS"
              },
              "kind": "StorageV2",
              "properties": {
                "supportsHttpsTrafficOnly": true
              }
            }
          ]
        }
      }
    },
    {
      "name": "dependentRgDeployment",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "resourceGroup": "dependentRG",
      "dependsOn": [
        "dependentRG",
        "masterRgDeployment"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.KeyVault/vaults",
              "name": "kvaNameTest1604",
              "apiVersion": "2015-06-01",
              "location": "West Europe",
              "properties": {
                "enabledForDeployment": false,
                "enabledForDiskEncryption": false,
                "enabledForTemplateDeployment": true,
                "tenantId": "[subscription().tenantId]",
                "accessPolicies": [
                  {
                    "objectId": "fc05639d-70eb-4175-a89b-eab7f883c691",
                    "tenantId": "[subscription().tenantId]",
                    "permissions": {
                      "keys": [
                        "get",
                        "list",
                        "update"
                      ],
                      "secrets": [
                        "get",
                        "list",
                        "update"
                      ]
                    }
                  }
                ],
                "sku": {
                  "name": "Standard",
                  "family": "A"
                },
                "networkAcls": {
                  "defaultAction": "Allow",
                  "bypass": "AzureServices"
                }
              }
            },
            {
              "type": "Microsoft.KeyVault/vaults/secrets",
              "name": "kvaNameTest1604/saConnectionString",
              "apiVersion": "2018-02-14",
              "location": "West Europe",
              "dependsOn": [
                "[resourceId('Microsoft.KeyVault/vaults', 'kvaNameTest1604')]"
              ],
              "properties": {
                "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', 'testsadj1604'), '2019-06-01').keys[0].value]"
              }
            }
          ]
        }
      }
    }
  ]
}

我很确定错误来自底部的 listKeys(),在我的真实模板中进行了一整天的反复试验(和 Google 狂热)。使用 listKeys() 和嵌套部署是一种拖累,但我真的不明白为什么它不应该工作。我确保在第二次部署中有一个 dependsOn。

这让我很费脑筋,有没有什么方法可以使用嵌套(内联)模板并引用不同资源组(但整体部署的一部分)中的存储帐户密钥?我还尝试在第一次部署中创建一个输出并在第二次部署中引用它,但没有效果。我完全不知所措,欢迎任何帮助!

要在单个模板中使用,您需要做一些事情:

  1. 在您的 keyvault 秘密部署中设置这个 属性:
    "expressionEvaluationOptions": {
      "scope": "inner"
    },

这将延迟表达式的计算,直到部署开始。

  1. 当你设置 #1 时,你需要为你需要的值定义参数(你不能再使用 "global" params/vars),你可以像你的例子一样硬编码所有的字符串,但我猜这不是您在 "real" 部署中所做的。定义参数并将值传递到该部署中。
  2. 你的 listKeys() 调用需要包含 storageAccount 的完整 resourceId,因为它在 separate/distinct 部署中 - 所以你需要提供 resourceGroup 名称参数 - 如果你在部署中交叉订阅(你的样本没有)你需要提供 subscriptionId 参数。

下面是一个工作示例...

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[concat('scratch', uniqueString(newGuid()))]"
    }
   },
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2018-05-01",
      "name": "masterRG",
      "location": "West Europe",
      "properties": {
      }
    },
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2018-05-01",
      "name": "dependentRG",
      "location": "West Europe",
      "properties": {
      }
    },
    {
      "name": "masterRgDeployment",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "resourceGroup": "masterRG",
      "dependsOn": [
        "masterRG"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "apiVersion": "2019-06-01",
              "type": "Microsoft.Storage/storageAccounts",
              "name": "[parameters('storageAccountName')]",
              "location": "West Europe",
              "sku": {
                "name": "Standard_GRS"
              },
              "kind": "StorageV2",
              "properties": {
                "supportsHttpsTrafficOnly": true
              }
            }
          ]
        }
      }
    },
    {
      "name": "dependentRgDeployment",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "resourceGroup": "dependentRG",
      "dependsOn": [
        "dependentRG",
        "masterRgDeployment"
      ],
      "properties": {
        "mode": "Incremental",
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "parameters":{
          "storageAccountName": {
            "value": "[parameters('storageAccountName')]"
          },
          "storageAccountResourceGroupName": {
            "value": "masterRG"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "storageAccountName": {
              "type": "string"
            },
            "storageAccountResourceGroupName": {
              "type": "string"
            }
          },
          "variables": {
            "vaultName": "[concat('kv-', parameters('storageAccountName'))]"
          },
          "resources": [
            {
              "type": "Microsoft.KeyVault/vaults",
              "name": "[variables('vaultName')]",
              "apiVersion": "2019-09-01",
              "location": "West Europe",
              "properties": {
                "enabledForDeployment": false,
                "enabledForDiskEncryption": false,
                "enabledForTemplateDeployment": true,
                "tenantId": "[subscription().tenantId]",
                "accessPolicies": [ ],
                "sku": {
                  "name": "Standard",
                  "family": "A"
                },
                "networkAcls": {
                  "defaultAction": "Allow",
                  "bypass": "AzureServices"
                }
              }
            },
            {
              "type": "Microsoft.KeyVault/vaults/secrets",
              "name": "[concat(variables('vaultName'), '/saConnectionString')]",
              "apiVersion": "2019-09-01",
              "location": "West Europe",
              "dependsOn": [
                "[resourceId('Microsoft.KeyVault/vaults', variables('vaultName'))]"
              ],
              "properties": {
                "value": "[listKeys(resourceId(parameters('storageAccountResourceGroupName'),'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value]"
              }
            }
          ]
        }
      }
    }
  ]
}