Search code examples
azuredevopsazure-resource-managerazure-managed-identityazure-bicep

Iterating through existing resources to get their MSI principal id


i want to add KeyVault access policies to existing resources.

For that, i put couple of web apps in my bicep code and i put them to the array:

var existingWebApps = [
  app1
  app2
  app3
  app4
]

resource app1 'Microsoft.Web/sites@2022-03-01' existing = {
  name: 'a1'
}

resource app2'Microsoft.Web/sites@2022-03-01' existing = {
  name: 'a2'
}

resource app3 'Microsoft.Web/sites@2022-03-01' existing = {
  name: 'a3'
}

resource app4 'Microsoft.Web/sites@2022-03-01' existing = {
  name: 'a4'
}

Then i want to iterate through existingWebApps list to create KV access policies for them:

resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
  name: keyVaultName
  location: location
  tags: tags
  properties: {
    sku: {
      family: 'A'
      name: 'standard'
    }
    tenantId: tenantId
    enablePurgeProtection: false
    enableSoftDelete: true
  }
}

resource keyVaultAccessPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = [for webApp in existingWebApps: {
  name: 'add'
  parent: keyVault
  properties: {
    accessPolicies: [
      {
        tenantId: tenantId
        objectId: webApp.identity.principalId
        permissions: {
          secrets: [
            'get'
            'list'
          ]
        }
      }
    ]
  }
}]

But it is not possbile because i get an error:

var existingWebApps: [Microsoft.Web/sites@2022-03-01, Microsoft.Web/sites@2022-03-01, Microsoft.Web/sites@2022-03-01, Microsoft.Web/sites@2022-03-01]

This expression is being used in the for-expression, which requires a value that can be calculated at the start of the deployment. You are referencing a variable which cannot be calculated at the start ("existingWebApps" -> "apiWeb"). Properties of apiWeb which can be calculated at the start include "apiVersion", "id", "name", "type".bicep(BCP178)

It seems like Microsoft.Web/sites@2022-03-01 does not export identity object from existing keyword so it is not possible to put principalIds to array.

My question is, how to access managed identity of existing resources in array in bicep code?


Solution

  • It is not possible to use arrays in this case because Bicep does support it yet. You probably need to rewrite the template so it contains every individual access policy.

    There is an open issue it on GitHub: Variable substitution logic does not work for variables with loop expressions