Rob Bowman
Rob Bowman

Reputation: 8711

Azure role assignment - BadRequestFormat

I'd like to create a storage account and add a role assignment to the service principal of an azure devops pipeline service connection - so that it's able to read a file in blob storage.

I already have a bicep module in a registry that gets used for creating storage accounts - this module is well used so that's not the problem.

My bicep is:

var storageAccountName = 'st${baseResourceNameAlpha}'
module storageAccount 'br:urlhere.azurecr.io/bicep/modules/storageaccount:v22.10.03.02' = {
  name: 'storageAccountDeployment'
  params: {
    name: storageAccountName
  }
}

resource storageAc 'Microsoft.Storage/storageAccounts@2022-05-01' existing = {
  name: storageAccountName
}
//corrected blobReaderRole thanks to comment from Thomas
//    var blobReaderRole = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
var blobReaderRole =  subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')
var principalId = 'principal id of my dev ops svc conn'

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  scope: storageAc
  name: guid(storageAc.id, principalId, blobReaderRole)
  properties: {
    roleDefinitionId: blobReaderRole
    principalId: principalId
    principalType: 'ServicePrincipal'
  }
}

This gives the following error:

BadRequestFormat The request was incorrectly formatted

Anyone see what I'm doing wrong?

Also, currently I get the principal id of the svc connection from the Enterprise Application page of the Azure portal. Get-AzADUser -UserPrincipalName doesn't seem to work for service principals. Is there another way?

Upvotes: 1

Views: 1700

Answers (1)

Thomas
Thomas

Reputation: 29502

The roleDefinitionId property needs to be the resourceId of the role definition:

roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')

Also the principalId property needs to be the objectId of the service principal not the objectId of the application. You can't really get it using pure bicep/arm. There is an open issue regarding that:

Before deploying your bicep template, you could always look it up using Az CLI or Az Powershell and pass it as a parameter of your template:

$appId = (az account show | ConvertFrom-Json).user.name
$principalId = (az ad sp show --id $appId | ConvertFrom-Json).id

Upvotes: 4

Related Questions