Mark
Mark

Reputation: 2001

Provision Access Policy with DependsOn

I'm trying to do the following:

Originally I was creating the Access Policy within the Keyvault, but I had to declare the AZ function as depending on the Key Vault (such that I could fetch its URI). Obviously, I was then unable to set Key Vault to depend on the AZ Function (since this would create a cyclic dependency). I then tried creating the AccessPolicy as another step, and marking it as depends on the KeyVault, and the AZ Function (thinking it would be provisioned last).

But for some reason, when looking at the deployment logs, it always seems like he's trying to deploy it first! Any help would be appreciated.

ARM Template truncated for brevity:


  "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.s. I know the way I'm creating my app settings is a work of art (sarcasm). Please don't judge me, just know that it works.

P.p.s Complete ARM Template: https://pastebin.com/mma4PyRu

Upvotes: 3

Views: 981

Answers (2)

bmoore-msft
bmoore-msft

Reputation: 8717

Try removing the apiVersion from the reference() function, that should delay the call until after the resource is provisioned. e.g.

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

Upvotes: 1

4c74356b41
4c74356b41

Reputation: 72171

your template is absolutely fine, so if this doesnt work it looks like a bug. having said that, you can always work around this by moving your accessPolicy assignment into a nested template:

{
   "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]"}
    }
}

You'd need to upload the template somewhere (which should consist of just your accessPolicy assignment

Reading: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-linked-templates#external-template

Upvotes: 2

Related Questions