I have a bicep template that has a number of resources defined in param arrays, one for storage accounts, another for function apps and so on. It then calls the resource specific modules, loops through the array for that specific resource and creates the resources.
I now need to do some role assigments on a storage account, using the principal id from a function app. I am trying to pass the list of function app principal ids to the role assignment module, but no matter what I try I am hitting an issue.
Here is what I currently have. I am trying to pass the output array of the function app pricipal ids to the storageRbac module, and the reference the id using an indexer inside the storageRbac module, but this doesn't work. If I try and reference the output funcAppsPrincId I get the error 'Does not exist in this context'.
main.bicep
param storageAccounts array = [
// Output Index 0
{
name: 'staccount01'
sku: {
name: 'Standard_LRS'
tier: 'Standard'
}
...
}
// Output Index 1
{
name: 'staccount02'
sku: {
name: 'Standard_LRS'
tier: 'Standard'
}
...
}]
param funcApps array = [
// Index 0
{
name: 'funcApp01'
kind: 'functionapp,linux'
...
}
// Index 1
{
name: 'funcApp02'
kind: 'functionapp,linux'
...
}]
module deployStorageAccount 'storageAccount.bicep' = [for storageAccount in storageAccounts: {
scope: resourceGroup(rlrFeRg)
name: storageAccount.name
params: {
...
}
}]
module deployFuncApps 'functionApp.bicep' = [for funcApp in funcApps: {
scope: resourceGroup(rlrFeRg)
name: funcApp.name
params: {
...
}
dependsOn: [
deployStorageAccount
]
}]
output funcAppsPrincId array = [for (funcApp, i) in funcApps: [
deployFuncApps[i].outputs.funcAppPrincipalId
]]
module storageRoleAssignment 'storageRbac.bicep' = {
name: 'storageAccountRbac'
params: {
rlrAdGroup: rlrAdGroup
storageAccounts: storageAccounts
funcAppsPrincipalIds: funcAppsPrincId
}
dependsOn: [
deployStorageAccount
deployFuncApps
]
}
functionApp.bicep
output funcAppPrincipalId string = functionApp.identity.principalId
storageRbac.bicep
param devsAdGroup string
param storageAccounts array
param funcAppsPrincipalIds array
var storageRoleAssignments = [
{
storageAccountName: storageAccounts[0].name
principalId: funcAppsPrincipalIds[0]
roleDefinition: 'Storage Blob Data Contributor'
principalType: 'ServicePrincipal'
}
{
storageAccountName: storageAccounts[0].name
principalId: funcAppsPrincipalIds[1]
roleDefinition: 'Storage Table Data Contributor'
principalType: 'ServicePrincipal'
}
{
storageAccountName: storageAccounts[1].name
principalId: devsAdGroup
roleDefinition: 'Storage Blob Data Contributor'
principalType: 'Group'
}
{
storageAccountName: storageAccounts[1].name
principalId: devsAdGroup
roleDefinition: 'Storage Table Data Contributor'
principalType: 'Group'
}
]
module storageRoleAssignment 'rbacStorageAccount.bicep' = [for storageRoleAssignment in storageRoleAssignments: {
name: 'rbac-${storageRoleAssignment.storageAccountName}'
params: {
storageAccountName: storageRoleAssignment.storageAccountName
principalId: storageRoleAssignment.principalId
roleDefinition: storageRoleAssignment.roleDefinition
principalType: storageRoleAssignment.principalType
}
}]
I can pass each individual principal id as a parameter like below, but ideally I'd like to pass the whole array to the storageRbac module and use the indexer there. Is there any way to achieve this?
main.bicep
module storageRoleAssignment 'storageRbac.bicep' = {
name: 'storageAccountRbac'
params: {
rlrAdGroup: rlrAdGroup
storageAccounts: storageAccounts
funcAppsPrincipalId1: deployFuncApps[0].outputs.funcAppPrincipalId
funcAppsPrincipalId2: deployFuncApps[1].outputs.funcAppPrincipalId
}
dependsOn: [
deployStorageAccount
deployFuncApps
]
}
You could use an intermediary module to deploy your functions:
functionApps.bicep
param funcApps array = []
module deployFuncApps 'functionApp.bicep' = [
for funcApp in funcApps: {
scope: resourceGroup()
name: funcApp.name
params: {
functionAppName: funcApp.name
}
}
]
output funcAppsPrincIds array = [
for (funcApp, i) in funcApps: [
deployFuncApps[i].outputs.funcAppPrincipalId
]
]
So from your main.bicep
file it could look like that:
module deployFuncApps 'functionApps.bicep' = {
scope: resourceGroup()
name: 'deploy-function-apps'
params: {
funcApps: funcApps
}
dependsOn: [
deployStorageAccount
]
}
module storageRoleAssignment 'storageRbac.bicep' = {
name: 'storageAccountRbac'
params: {
...
funcAppsPrincipalIds: deployFuncApps.outputs.funcAppsPrincIds
}
dependsOn: [
deployStorageAccount
deployFuncApps
]
}