Home > Software engineering >  Azure Bicep - Referencing a variable that cannot be calculated at the start
Azure Bicep - Referencing a variable that cannot be calculated at the start

Time:08-05

I need to:

  • create a data factory
  • create a storage account
  • create a function app
  • add a role assignment for the data factory to the storage account
  • add a role assignment for the function app to the storage account

The data factory is created in a separate module from the "main" bicep. This is to prevent the "main" template being so large it is difficult to work with - one of the main benefits of bicep over arm templates. Same goes for creation of the function app.

For the role assignment I have:

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
  name: guid(storageAccount.id, contributorRoleId, adfDeploy.outputs.dfId)

VSCode then presents the following "problem":

This expression is being used in an assignment to the "name" property of the "Microsoft.Authorization/roleAssignments" type, which requires a value that can be calculated at the start of the deployment. Properties of adfDeploy which can be calculated at the start include "name".

I can't compose the storageAccount Id from a string (subscription/rg/resource etc.) because the subscription id is also determined at runtime since the same main bicep is called for deployment to multiple subscriptions.

Is there any way to achieve what's needed without pulling back the creation of the data factory and function apps to the "main" bicep?

CodePudding user response:

You could create a generic module for storage role assignment:

// storage-account-role-assignment.bicep
param storageAccountName string
param principalId string
param roleId string

// Get a reference to the storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' existing = {
  name: storageAccountName
}

// Grant permissions to the storage account
resource storageAccountAppRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' =  {
  name: guid(storageAccount.id, roleId, principalId)
  scope: storageAccount
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleId)
    principalId: principalId
  }
}

Then invoke this module from where you are creating data factory or function app:

// function-app.bicep
...
resource functionApp 'Microsoft.Web/sites@2021-03-01' = {
  name: functionAppName
  kind: 'functionapp'
  identity: {
    type: 'SystemAssigned'
  }
  ...
}

// Create role assignment
module roleAssignment 'storage-account-role-assignment.bicep' = {
  name: 'function-storage-account-role-assignment'
  scope: resourceGroup()
  params:{
    storageAccountName: storageAccountName
    roleId: '<role-id>'
    principalId: functionApp.identity.principalId
  }
}

// data-factory.bicep
...
resource dataFactory 'Microsoft.DataFactory/factories@2018-06-01' = {
  name: name
  identity: {
    type: 'SystemAssigned'
  }
  ...
}

// Create role assignment
module roleAssignment 'storage-account-role-assignment.bicep' = {
  name: 'data-facory-storage-account-role-assignment'
  scope: resourceGroup()
  params:{
    storageAccountName: storageAccountName
    roleId: '<role-id>'
    principalId: dataFactory.identity.principalId
  }
}
  • Related