【问题标题】:Provision Access Policy with DependsOn使用 DependsOn 提供访问策略
【发布时间】:2019-10-09 14:24:21
【问题描述】:

我正在尝试执行以下操作:

  • 创建密钥库(有效)
  • 创建一个 AZ 函数(有效)
  • 使用 keyvault 的 vaultURI 作为 AZ 功能的应用设置(有效)
  • 为 AZ 功能提供托管标识(有效)
  • 创建一个访问策略,让 AZ 函数可以访问密钥库(哎呀!)

最初我是在 Keyvault 中创建访问策略,但我必须将 AZ 函数声明为依赖于 Key Vault(这样我才能获取它的 URI)。显然,我无法将 Key Vault 设置为依赖于 AZ 函数(因为这会产生循环依赖)。然后,我尝试创建 AccessPolicy 作为另一个步骤,并将其标记为取决于 KeyVault 和 AZ 功能(认为它会在最后配置)。

但由于某种原因,在查看部署日志时,似乎他总是在尝试先部署它!任何帮助,将不胜感激。

为简洁起见截断了 ARM 模板:


  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "2016-10-01",
      "name": "[variables('keyVaultName')]",
      "location": "[ResourceGroup().location]",
      "properties": {
        "sku": {
          "family": "A",
          "name": "Standard"
        },
        "tenantId": "[subscription().tenantId]",
        "accessPolicies": [
          {
            "tenantId": "[subscription().tenantId]",
            "objectId": "[parameters('userId')]",
            "permissions": {
              "keys": [
                "Get",
                "List",
                "Update",
                "Create",
                "Import",
                "Delete",
                "Recover",
                "Backup",
                "Restore"
              ],
              "secrets": [
                "Get",
                "List",
                "Set",
                "Delete",
                "Recover",
                "Backup",
                "Restore"
              ],
              "certificates": [
                "Get",
                "List",
                "Update",
                "Create",
                "Import",
                "Delete",
                "Recover",
                "Backup",
                "Restore",
                "ManageContacts",
                "ManageIssuers",
                "GetIssuers",
                "ListIssuers",
                "SetIssuers",
                "DeleteIssuers"
              ]
            }
          }
        ],
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false
      }
    },
    {
      "type": "Microsoft.KeyVault/vaults/accessPolicies",
      "name": "[concat(variables('keyVaultName'),'/add')]",
      "apiVersion": "2018-02-14",
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', variables('functionName'))]",
        "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]"
      ],
      //tried both the above and the below
      "dependsOn": [
        "[variables('keyVaultName')]",
        "[variables('functionName')]"
      ],
      "properties": {
        "accessPolicies": [
          {
            "tenantId": "[subscription().tenantId]",
            "objectId": "[reference(concat(resourceId('Microsoft.Web/sites', variables('functionName')), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]",
            "permissions": {
              "keys": [
              ],
              "secrets": [
                "Get",
                "Set",
                "Delete"
              ],
              "certificates": [
              ]
            }
          }
        ]
      }
    },
.
.
.
.
.
.
.
.
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2016-08-01",
      "name": "[variables('functionName')]",
      "location": "[ResourceGroup().location]",
      "dependsOn": [
        "[variables('planName')]",
        "[variables('appInsightsName')]",
        "[variables('storageAccName')]",
        "[variables('keyVaultName')]",
        "[variables('databaseName')]"
      ],
      "kind": "functionapp",
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": {
        "serverFarmId": "[variables('planName')]",
        "enabled": true,
        "reserved": false
      },
      "resources": [
        {
          "apiVersion": "2015-08-01",
          "name": "connectionstrings",
          "type": "config",
          "dependsOn": [
            "[variables('functionName')]",
            "[variables('databaseName')]"
          ],
          "properties": {
          }
        },
        {
          "apiVersion": "2015-08-01",
          "name": "appsettings",
          "type": "config",
          "dependsOn": [
            "[variables('functionName')]",
            "[variables('appInsightsName')]",
            "[variables('storageAccName')]",
            "[variables('keyVaultName')]"
          ],
          "properties": "[union(variables('completeAppSettings'),json(concat('{ AzureWebJobsStorage:\"', concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccName')), '2019-04-01').keys[0].value), '\", WEBSITE_CONTENTAZUREFILECONNECTIONSTRING:\"',\tconcat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccName')), '2019-04-01').keys[0].value), '\", WEBSITE_CONTENTSHARE:\"', variables('functionName'), '\", APPINSIGHTS_INSTRUMENTATIONKEY:\"', reference(concat('microsoft.insights/components/', variables('appInsightsName'))).InstrumentationKey, '\", KeyVaultUri:\"', reference(concat('Microsoft.KeyVault/vaults/', variables('keyVaultName'))).vaultUri, '\"}')))]"
        },
        {
          "type": "slots",
          "apiVersion": "2016-08-01",
          "name": "[variables('functionStagingName')]",
          "location": "[ResourceGroup().location]",
          "dependsOn": [
            "[variables('functionName')]",
            "[variables('keyVaultName')]"
          ],
          "kind": "functionapp",
          "properties": {
            "enabled": false,
            "serverFarmId": "[variables('planName')]"
          }
        }
      ]
    }
  ]

附:我知道我创建应用程序设置的方式是一件艺术品(讽刺)。请不要评判我,只要知道它有效。

P.p.s 完整的 ARM 模板:https://pastebin.com/mma4PyRu

【问题讨论】:

    标签: json azure azure-functions azure-resource-manager azure-deployment


    【解决方案1】:

    您的模板绝对没问题,所以如果这不起作用,它看起来像一个错误。话虽如此,您始终可以通过将您的 accessPolicy 分配移动到嵌套模板中来解决此问题:

    {
       "type": "Microsoft.Resources/deployments",
       "apiVersion": "2018-05-01",
       "name": "linkedTemplate",
       "dependsOn": [
           "[variables('keyVaultName')]",
           "[variables('functionName')]"
       ],
       "properties": {
           "mode": "Incremental",
           "templateLink": {
           "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
           "contentVersion":"1.0.0.0"
        },
        "parameters": {
            "managedIdentityId":{"value": "[reference(concat(resourceId('Microsoft.Web/sites', variables('functionName')), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]"}
        }
    }
    

    您需要将模板上传到某处(应该只包含您的 accessPolicy 分配

    阅读:https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-linked-templates#external-template

    【讨论】:

    • 感谢您查看。是的,我将嵌套模板作为最后的手段,但我认为我必须退回到它们。
    • 我在托管标识事物参考中看到了一些错误,无论如何,它似乎只是在部署开始时发生。如果发生这种情况,您需要移动引用函数以检索嵌套模板中的托管标识,然后它会起作用(因为它只会在嵌套模板启动时启动)
    • 使用内联嵌套模板进行了尝试,但没有成功。然后我更改了逻辑,因此我没有将托管标识 id 作为参数传递,而是传递函数名称,然后在内部检索标识......仍然不起作用。弄清楚如何使用链接模板(因为我必须将其上传到某处)使其工作需要一些阅读,因为这是 DevOps CICD 管道的一部分。老实说,简单的解决方法是简单地运行模板两次。第一次会失败,但第二次会成功。这是一种糟糕的方式,但它是一种方式。
    【解决方案2】:

    尝试从 reference() 函数中删除 apiVersion,这应该会延迟调用,直到配置资源之后。例如

    [reference(concat(resourceId('Microsoft.Web/sites', variables('functionName')), '/providers/Microsoft.ManagedIdentity/Identities/default')).principalId]"
    

    【讨论】:

    • 很遗憾我的情况并没有改善。可以说现在实际上变得更糟了!错误消息:消息 = 部署模板验证失败:“模板中未定义资源 'Microsoft.Web/sites/REDACTEDFORPRIVACY/providers/Microsoft.ManagedIdentity/Identities/default'。
    • 好的,必须查看您的整个部署...如果资源部署在单独的模板中,那么您必须提供 apiVersion。但在这种情况下,函数的评估应该延迟到部署。如果它在同一个模板中,那么您不需要 apiVersion 也具有延迟部署的相同效果。你可以在这里发帖或者直接给我发电子邮件,如果这样更好的话 - bmoore at microsoft
    • 非常感谢您的帮助,但这不是必需的。我选择使用嵌套模板。您对 apiVersion 的评论很高兴知道!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多