I'm trying to assign the role "Storage Blob Data Contributor (Preview)" to a specific storage container via arm template. But I just can't figure out the correct syntax.
This is what I have:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "string",
"allowedValues": [
"Contributor",
"Reader",
"StorageBlobDataContributor"
],
"metadata": {
"description": "Built-in role to assign"
}
}
},
"variables": {
"apiVersion": "2017-05-01",
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"StorageBlobDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]",
"TestVariable": "[concat('STORAGEACCOUNTNAME','/Microsoft.Authorization/',guid(subscription().subscriptionId))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts/providers/roleAssignments",
"apiVersion": "[variables('apiVersion')]",
"name": "[variables('TestVariable')]",
"properties": {
"roleDefinitionId": "[variables('Reader')]",
"principalId": "[parameters('principalId')]"
}
},
{
"type": "Microsoft.Storage/storageAccounts/STORAGEACCOUNTNAME/blobServices/containers/blobCONTAINERNAME/providers/Microsoft.Authorization/roleAssignments",
"apiVersion": "[variables('apiVersion')]",
"name": "STORAGEACCOUNTNAME/blobServices/containers/default/blobCONTAINERNAME/Microsoft.Authorization/NEW-GUID",
"properties": {
"roleDefinitionId": "[variables('StorageBlobDataContributor')]",
"principalId": "[parameters('principalId')]"
}
}
],
"outputs": {}
}
I can attach the reader role to the storage account itself succesfully.
But for the container I get the following error:
new-AzResourceGroupDeployment : 09:21:24 - Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The template resource
'STORAGEACCOUNTNAME/blobServices/containers/CONTAINERNAME/Microsoft.Authorization/GUID' for type
'Microsoft.Storage/storageAccounts/STORAGEACCOUNTNAME/blobServices/default/containers/CONTAINERNAME/providers/Microsoft.Authorization/roleAssignments' at line '44' and column '9' has incorrect
segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see
https://aka.ms/arm-template/#resources for usage details.'.
I have tried so many ways trying to attach the role, that I out of idea's.
Can someone help me?
you need to construct something like this:
resourceId/Microsoft.Authorization/roleAssignments/NEW-GUID
and resourceId is normally being constructed as
type: provider/namespace
name: name
provider/namespace/name
for example, for subnet it would be (notice it takes 1 segment from each line in turn, except for the first one, first one is always 2 segments):
type: microsoft.network/virtualnetworks/subnets
name: vnetName/subnetName
microsoft.network/virtualnetworks/vnetName/subnets/subnetName
if that is even possible it would look like something like this:
"type": "Microsoft.Storage/storageAccounts/blobServices/containers/providers/roleAssignments",
"name": "STORAGEACCOUNTNAME/default/CONTAINERNAME/Microsoft.Authorization/NEW-GUID"
Microsoft.Storage/storageAccounts/STORAGEACCOUNTNAME/containers/CONTAINERNAME/providers/Microsoft.Authorization/roleAssignments/NEW-GUID
Made some little adjustments:
"type": "Microsoft.Storage/storageAccounts/blobServices/containers/providers/roleAssignments",
"name": "STORAGEACCOUNTNAME/default/CONTAINERNAME/Microsoft.Authorization/NEW-GUID"
This way I can assign roles on the container itself. Thanks 4c74356b41 for pointing me in the right direction
Using Erik's answer above (which I've up-voted of course, thx Erik!), I was able to solve the similar issue for RBAC permissions on a Queue of a Storage Account using ARM templates.
Here is an example ARM template for adding Sender role to a single Queue of a Storage Account...
<..snip..>
"parameters": {
"PrincipalId": {
"type": "string",
"minLength": 36,
"maxLength": 36
}
},
"variables": {
"SubscriptionId": "[concat('/subscriptions/', subscription().subscriptionId)]",
"RoleDefinitions": "[concat(variables('SubscriptionId'), '/providers/Microsoft.Authorization/roleDefinitions/')]",
"QueueSenderRole": "c6a89b2d-59bc-44d0-9896-0f6e12d7b80a"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts/queueServices/queues/providers/roleAssignments",
"name": "mystorageaccount/default/myqueue/Microsoft.Authorization/00000000-1234-0000-5678-000000000000", // NB example only; pick an idempotent but unique value
"apiVersion": "2018-09-01-preview",
"properties": {
"roleDefinitionId": "[concat(variables('RoleDefinitions'), variables('QueueSenderRole'))]",
"principalId": "[parameters('PrincipalId')]"
}
}
]
Related
Background Information
I have the following arm template that assigns a RBAC to a managed ID;
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "string",
"allowedValues": [
"Owner",
"Contributor",
"Reader",
"StorageQueueDataContributor",
"StorageTableDataContributor"
],
"metadata": {
"description": "Built-in role to assign"
}
},
"roleNameGuid": {
"type": "string",
"defaultValue": "[newGuid()]",
"metadata": {
"description": "A new GUID used to identify the role assignment"
}
}
},
"variables": {
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"StorageQueueDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','974c5e8b-45b9-4653-ba55-5f855dd0fb88')]",
"StorageTableDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]"
},
"resources": [
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[parameters('roleNameGuid')]",
"properties": {
"roleDefinitionId": "[variables(parameters('builtInRoleType'))]",
"principalId": "[parameters('principalId')]"
}
}
]
}
and I'm calling it from a powershell script like this:
az deployment group create `
--resource-group $RESOURCE_GROUP `
--template-file "./rbac-role.json" `
--parameters principalId=$objectid builtInRoleType=StorageTableDataContributor roleNameGuid=0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3
So far so good. But now I'd like to be able to assign mutiple RBAC roles instead of just one. I tried to call it twice, once per role type but that fails with an error:
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n \"error\": {\r\n \"code\": \"RoleAssignmentUpdateNotPermitted\",\r\n \"message\": \"Tenant ID, application ID, principal ID, and scope are not allowed to be updated.\"\r\n }\r\n}"}]}}
What I've Tried So far
I've tried to pass arrays as parameters. In reading the docs, it seems that ARM Template parameters can accept arrays.
So I've updated my powershell code to look like this:
$RoleTypeArray = #(
'StorageQueueDataContributor'
'StorageTableDataContributor'
)
$RoleGuidArray = #(
'974c5e8b-45b9-4653-ba55-5f855dd0fb88'
'0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
)
az deployment group create `
--resource-group $RESOURCE_GROUP `
--template-file "./rbac-role.json" `
--parameters principalId=$objectid builtInRoleType=$RoleTypeArray roleNameGuid=$RoleGuidArray
And the template like this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "array",
"defaultValue": [
"Owner",
"Contributor",
"Reader",
"StorageQueueDataContributor",
"StorageTableDataContributor"
],
"metadata": {
"description": "Built-in role to assign"
}
},
"roleNameGuid": {
"type": "array",
"defaultValue": [
"8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"b24988ac-6180-42a0-ab88-20f7382dd24c",
"acdd72a7-3385-48ef-bd42-f606fba81ae7",
"974c5e8b-45b9-4653-ba55-5f855dd0fb88",
"0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3"
],
"metadata": {
"description": "A new GUID used to identify the role assignment"
}
}
},
"variables": {
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"StorageQueueDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','974c5e8b-45b9-4653-ba55-5f855dd0fb88')]",
"StorageTableDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]"
},
"resources": [
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[parameters('roleNameGuid')[0]]",
"properties": {
"roleDefinitionId": "[variables(parameters('builtInRoleType')[0])]",
"principalId": "[parameters('principalId')]"
}
}
]
}
For now, I've just hardcoded the index to 0 but if this is the right tree to bark up, I'll have to figure out how to loop? Or I can create the same section twice in the JSON ARM template file maybe - once for each of the two roles?
For now, the error I'm getting is:
Failed to parse JSON: StorageQueueDataContributor StorageTableDataContributor
Error detail: Expecting value: line 1 column 1 (char 0)
It's not clear to me at what point its dying.
Adding some debug statements but any tips would be appreciated.
EDIT 1
I've modified my ARM Template to look like this:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "array",
"defaultValue": [
"Owner",
"Contributor",
"Reader",
"StorageQueueDataContributor",
"StorageTableDataContributor"
],
"metadata": {
"description": "Built-in role to assign"
}
}
},
"variables": {
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"StorageQueueDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','974c5e8b-45b9-4653-ba55-5f855dd0fb88')]",
"StorageTableDataContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]"
},
"resources": [
{
"copy": {
"name": "roleAssignment",
"count": "[length(parameters('builtInRoleType'))]"
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[guid(subscription().subscriptionId, resourceGroup().name, parameters('builtInRoleType')[copyIndex()], parameters('principalId'))]",
"properties": {
"roleDefinitionId": "[parameters('builtInRoleType')[copyIndex()]]",
"principalId": "[parameters('principalId')]"
}
}
]
}
This is how I'm calling it:
az deployment group create `
--resource-group $RESOURCE_GROUP_NAME `
--template-file "./rbac-role.json" `
--parameters `
principalId=$objectid `
builtInRoleType="['StorageQueueDataContributor', 'StorageTableDataContributor']"
But the error I'm getting is
{
"status": "Failed",
"error": {
"code": "BadRequestFormat",
"message": "The request was incorrectly formatted."
}
}
I think it could be related to the roleDefinitionID.
This is the second time I'm testing the refactored code. The first time through though, the roleDefinitionID still looked like this:
"roleDefinitionId": "[variables(parameters('builtInRoleType')[0])]",
"principalId": "[parameters('principalId')]"
And I ended up with the StorageQueueDataContributor role being assigned twice.
Multiple things here.
The role assignment name has to be unique. Once an assignment has been created you can't change it so you can't use the same guid otherwise it looks like you're trying to update the role assignment which is not allowed.
You can't use powershell array as input parameter. Using az cli, a valid array parameter would look like that:
az deployment group create `
--resource-group $RESOURCE_GROUP `
--template-file "./rbac-role.json" `
--parameters `
principalId=$objectid `
builtInRoleType="['StorageQueueDataContributor', 'StorageTableDataContributor']" `
roleNameGuid="['974c5e8b-45b9-4653-ba55-5f855dd0fb88', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3']"
To remove the need of generating unique role name, you could use the guid() function:
Creates a value in the format of a globally unique identifier based on the values provided as parameters.
So this will generate a unique string but you can run the same template multiple time, it will always be the same unique string:
"name": "[guid(subscription().subscriptionId, resourceGroup().name, parameters('builtInRoleType')[0]], parameters('principalId'))]",
If you want to create multiple assignment at the same time, you could use the copy() function:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string"
},
"builtInRoleType": {
"type": "array",
"allowedValues":[
"Owner",
"Contributor",
"Reader",
"StorageQueueDataContributor",
"StorageTableDataContributor"
]
}
},
"variables": {
"Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"Contributor": "'b24988ac-6180-42a0-ab88-20f7382dd24c",
"Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7",
"StorageQueueDataContributor": "974c5e8b-45b9-4653-ba55-5f855dd0fb88",
"StorageTableDataContributor": "0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3"
},
"resources": [
{
"copy": {
"name": "roleAssignment",
"count": "[length(parameters('builtInRoleType'))]"
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2020-04-01-preview",
"name": "[guid(subscription().subscriptionId, resourceGroup().name, parameters('builtInRoleType')[copyIndex()], parameters('principalId'))]",
"properties": {
"roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleAssignments', variables(parameters('builtInRoleType')[copyIndex()]))]",
"principalId": "[parameters('principalId')]"
}
}
]
}
then you could just invoke the template like that:
az deployment group create `
--resource-group $RESOURCE_GROUP `
--template-file "./rbac-role.json" `
--parameters `
principalId=$objectid `
builtInRoleType="['StorageQueueDataContributor', 'StorageTableDataContributor']"
I need to get the latest version of the Key in the output section of the arm template(generated inside Azure's Key Vault) which is generated from an ARM template . How can I get that ? I need to use the output as input for my next Job in pipeline.
Newer versions of the Key Vault provider for ARM deployments support creating keys, which you can reference as shown in the example ARM template below.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vaultName": {
"type": "string"
},
"objectId": {
"type": "string",
"metadata": {
"description": "The unique principal ID within the tenant to which key wrap and unwrap permissions are given."
}
},
"keyName": {
"type": "string",
"defaultValue": "test-key"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"tenantId": {
"type": "string",
"defaultValue": "[subscription().tenantId]",
"metadata": {
"description": "Tenant ID of the ACtive Directory to authenticate access. Default is the current subscription's tenant ID."
}
}
},
"variables": {
"apiVersion": "2019-09-01"
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "[variables('apiVersion')]",
"name": "[parameters('vaultName')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"family": "A",
"name": "standard"
},
"tenantId": "[parameters('tenantId')]",
"accessPolicies": [
{
"tenantId": "[parameters('tenantId')]",
"objectId": "[parameters('objectId')]",
"permissions": {
"keys": [
"wrapKey",
"unwrapKey"
]
}
}
]
}
},
{
"type": "Microsoft.KeyVault/vaults/keys",
"apiVersion": "[variables('apiVersion')]",
// The name must include the vault name and key name separated by a slash.
"name": "[concat(parameters('vaultName'), '/', parameters('keyName'))]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]"
],
"properties": {
"kty": "RSA",
"keySize": 4096,
"keyOps": [
"wrapKey",
"unwrapKey"
]
}
}
],
"outputs": {
"keyName": {
"type": "string",
"value": "[parameters('keyName')]"
},
// Despite the delimited resource name above, we need to construct a 2-parameter resource ID to reference the created key.
"keyUri": {
"type": "string",
"value": "[reference(resourceId('Microsoft.KeyVault/vaults/keys', parameters('vaultName'), parameters('keyName'))).keyUri]"
},
"keyVersionUri": {
"type": "string",
"value": "[reference(resourceId('Microsoft.KeyVault/vaults/keys', parameters('vaultName'), parameters('keyName'))).keyUriWithVersion]"
}
}
}
Note the comments about how you create and reference the keys differently. Simply using the reference() template function against the delimited name results in an invalid template, so you must construct a resourceId() despite being in the sample template.
Adjust access policies as needed. This example gives the principal you pass key wrap and unwrap capabilities, which you can use for block encryption ciphers.
To use this template (e.g. saved as keyvault-template.json),
az group create -n rg-mytestkv -l westus2
az deployment group create -g rg-mytestkv --template-file keyvault-template.json --parameters vaultName=mytestkv objectId=$(az account show --query id)
I was trying to deploy queue service as optional parameter with default blank value, template first create storage account then queue service as nested resource. template throwing error Message=Deployment template validation failed: 'The template resource '[concat(parameters('storageName'),'/default/',parameters('storagequeues')[copyIndex()])]'
at line '91' and column '9' is not valid: The language expression property array index '0' is out of bounds.
for some reason schema validating nested resource name before condition evaluation. Is this expected behavior ? if not please suggest work around.
I have tried with condition "condition": "[not(contains(parameters('storagequeues'),'none'))]", and Having defaultvalue="none" then it won\t create queue. it works fine but this is not desired way of doing.
This template creating a queue under a storage account may meet you need.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Specifies the name of the Azure Storage account."
}
},
"queueName": {
"type": "string",
"metadata": {
"description": "Specifies the name of the blob container."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Specifies the location in which the Azure Storage resources should be deployed."
}
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"accessTier": "Hot"
},
"resources": [
{
"type": "queueServices/queues",
"apiVersion": "2019-06-01",
"name": "[parameters('queueName')]",
"dependsOn": [
"[parameters('storageAccountName')]"
]
}
]
}
]
}
I have seen this 'The language expression property array index '0' is out of bounds.' error before, but the reason may different. I cannot see your defaultValue in 'storagequeue', maybe the null array cause this issue. You can refer to this.
I am facing following error "The request to create role assignment 'c*****************5' is not valid. Role assignment scope '/subscriptions/c**********************5/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccountname' must match the scope specified on the URI"
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"defaultValue": "My AD app ID",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "string",
"defaultValue": "Reader",
"allowedValues": [
"Owner",
"Contributor",
"Reader"
],
"metadata": {
"description": "Built-in role to assign"
}
},
"roleNameGuid": {
"type": "string",
"defaultValue": "random guid (i am getting this guid using following PS command "[System.Guid]::NewGuid().toString()")",
"metadata": {
"description": "A new GUID used to identify the role assignment"
}
}
},
"variables": {
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'this is my ownerid')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'this is my contributor id')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'this is my reader id')]",
"scope": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/', 'this is my storage account name')]"
},
"resources": [
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2014-10-01-preview",
"name": "[parameters('roleNameGuid')]",
"properties": {
"roleDefinitionId": "[variables(parameters('builtInRoleType'))]",
"principalId": "[parameters('principalId')]",
"scope": "[variables('scope')]"
}
}
]
}
This is a common problem for assigning a role assignment at a scope higher than the scope of the deployment. In your case the deployment is at the Resource Group level and you are trying to assign the scope at the Subscription level (which is higher level than Resource Group).
Solution: You will need to use Nested Template deployment.
To view a sample, check this documentation link and search for section "Assign Role at Scope" in this documentation: Create resources at Subscription level
I have tried
{
"apiVersion": "2016-07-01",
"name": "[concat(resourceGroup().name,'/Microsoft.Authorization/',variables('principalId'))]",
"type": "Microsoft.Authorization/roleAssignments",
"properties": {
"roleDefinitionId": "[variables('owner')]",
"principalId": "[parameters('msi').principalId]",
"scope": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',resourceGroup().name)]"
}
},
but it gives the following error
Deployment template validation failed: 'The template resource
'sf-gateway/Microsoft.Authorization/5e60879d-b9c0-4e11-9548-9d92ed244eef' for type 'Microsoft.Authorization/roleAssignments' at line '1' and
column '3432' has incorrect segment lengths. A nested resource type
must have identical number of segments as its resource name. A root
resource type must have segment length one greater than its resource
name. Please see https://aka.ms/arm-template/#resources for usage
details.'. (Code: InvalidTemplate)
I dont fully understand whats needed to be changed.
I want to give the principal ownership over the resourcegroup
I want to give the principal ownership over the resourcegroup
You could get the template demo code from this link. If you create the template with VS you could get it directly from the template. It works correctly for me.
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string",
"metadata": {
"description": "The principal to assign the role to"
}
},
"builtInRoleType": {
"type": "string",
"allowedValues": [
"Owner",
"Contributor",
"Reader"
],
"metadata": {
"description": "Built-in role to assign"
}
},
"roleNameGuid": {
"type": "string",
"metadata": {
"description": "A new GUID used to identify the role"
}
}
},
"variables": {
"Owner": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
"Contributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
"Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"scope": "[resourceGroup().id]"
},
"resources": [
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2017-05-01",
"name": "[parameters('roleNameGuid')]",
"properties": {
"roleDefinitionId": "[variables(parameters('builtInRoleType'))]",
"principalId": "[parameters('principalId')]",
"scope": "[variables('scope')]"
}
}
]
}
azuredeploy.parameters.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"value": "principalId"
},
"builtInRoleType": {
"value": "Owner"
},
"roleNameGuid": {
"value": "Guid name"
}
}
}
Test Result:
The error is happening because the name has more segments, i.e. components demarcated with a slash, than the type, as explained in more detail here: Resolve errors for invalid template.
There's a related discussion here; if you can get the GUID for the resource and pass that in for name, it will have fewer segments than the type.