In my current project I'm working with pre-created App Registration Service Principals in Azure AD. I'm using an ARM template to create a StorageV2 account plus some blob containers, then create a roleAssignment giving Storage Blob Contributor rights to one of the Service Principals. The relevant section of the ARM template is at the end of this post.
What I've found is that if I take the ObjectId
of a regular AD user, such as myself or my colleague, and set that as PrincipalId
, the script runs correctly. However, I can't get this to work with a Service Principal.
If I use the Service Principal's ObjectId
, then I get the following error:
Deployment failed. Correlation ID: 40e0c146-165a-47c0-b022-ac04781d8194. {
"error": {
"code": "PrincipalTypeNotSupported",
"message": "Principals of type Application cannot validly be used in role assignments."
}
}
Having spotted some suggestions for Azure Powershell users that I should use Application (Client) Id instead, I tried that, but get the following error (Guids redacted):
Deployment failed. Correlation ID: 5c725a51-230a-4d85-bb61-b2f4cdf849ff. {
"error": {
"code": "PrincipalNotFound",
"message": "Principal 9f****30 does not exist in the directory db****75."
}
}
So the ObjectId
it can find but not use, and the ClientId
it can't find.
I have found that if I use Azure Powershell and use the New-AzureRmRoleAssignment
command, I can reproduce the PrincipalTypeNotSupported
error by providing the Service Principal's ObjectId
to the -ObjectId
switch. However, that command also has a -ServicePrincipalName
switch as an alternative, and if I give that the Service Principal's ClientId
, it works!
Is there any equivalent of -ServicePrincipalName
for the ARM templates, and if not, is there any other way to achieve this? I can use Azure Powershell as a workaround, but it's messier than I'd like.
If this is a feature gap, where's the best place to report it?
Relevant section of ARM template follows:
"resources": [
{
"name": "[variables('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"location": "[resourceGroup().location]",
"apiVersion": "2018-07-01",
"sku": {
"name": "[parameters('storageAccountSku')]"
},
"dependsOn": [],
"tags": {
"displayName": "Storage Account"
},
"kind": "StorageV2",
"properties": {
"accessTier": "Hot",
"supportsHttpsTrafficOnly": true,
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Deny"
}
},
"resources": [
{
"type": "blobServices/containers",
"name": "[concat('default/', variables('myBlobContainerName'))]",
"apiVersion": "2018-07-01",
"dependsOn": [
"[variables('storageAccountName')]"
],
"resources": [
{
"type": "Microsoft.Authorization/roleAssignments",
"name": "[variables('myRoleAssignmentGuid')]",
"apiVersion": "2018-07-01",
"properties": {
"roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe')]",
"principalId": "[variables('myPrincipalId')]"
},
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'), '/blobServices/default/containers/', variables('myBlobContainerName'))]"
]
}
]
}
]
}
]