Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AVM Question/Feedback]: RBAC Interface #4282

Closed
1 task done
Grant-Rc opened this issue Jan 24, 2025 · 3 comments
Closed
1 task done

[AVM Question/Feedback]: RBAC Interface #4282

Grant-Rc opened this issue Jan 24, 2025 · 3 comments
Assignees
Labels
Needs: Attention 👋 Reply has been added to issue, maintainer to review Needs: Core Team 🧞 This item needs the AVM Core Team to review it Type: AVM 🅰️ ✌️ Ⓜ️ This is an AVM related issue Type: Question/Feedback 🙋 Further information is requested or just some feedback

Comments

@Grant-Rc
Copy link

Check for previous/existing GitHub issues

  • I have checked for previous/existing GitHub issues

Description

Hey

I'm confused as to why avm/res/resources/resource-group/modules/nested_roleAssignments.bicep only contains limited built in role names but there is no mention as to why in the notes. It only says you can provide the display name

roleDefinitionIdOrName | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.

Then nested_roleAssignments.bicep does a lookup

var builtInRoleNames = {
  Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
  Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
  'Quota Request Operator': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '0e5f05e5-9ab9-446b-b98d-1e2157c94125'
  )
  Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
  'Resource Policy Contributor': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '36243c78-bf99-498c-9df9-86d9f8d28608'
  )
  'Role Based Access Control Administrator': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    'f58310d9-a9f6-439a-9e8d-f62e7b41a168'
  )
  'Tag Contributor': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '4a9ae827-6dc8-4573-8ac7-8239d42aa03f'
  )
  'Template Spec Contributor': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '1c9b6475-caf0-4164-b5a1-2142a7116f4b'
  )
  'Template Spec Reader': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '392ae280-861d-42bd-9ea5-08ee6d83b80e'
  )
  'User Access Administrator': subscriptionResourceId(
    'Microsoft.Authorization/roleDefinitions',
    '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
  )
}

If the display name is not listed it throws you the error

{"code":"InvalidRoleDefinitionId","message":"The role definition ID 'Virtual Machine Contributor' is not valid."}
@Grant-Rc Grant-Rc added Needs: Triage 🔍 Maintainers need to triage still Type: AVM 🅰️ ✌️ Ⓜ️ This is an AVM related issue Type: Question/Feedback 🙋 Further information is requested or just some feedback labels Jan 24, 2025
@Grant-Rc
Copy link
Author

The formatted Role Assign does a Else where is will do a resource ID look up but this does not accept a "Name"

var formattedRoleAssignments = [
  for (roleAssignment, index) in (roleAssignments ?? []): union(roleAssignment, {
    roleDefinitionId: builtInRoleNames[?roleAssignment.roleDefinitionIdOrName] ?? (contains(
        roleAssignment.roleDefinitionIdOrName,
        '/providers/Microsoft.Authorization/roleDefinitions/'
      )
      ? roleAssignment.roleDefinitionIdOrName
      : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName))
  })
]

@microsoft-github-policy-service microsoft-github-policy-service bot added the Status: Response Overdue 🚩 When an issue/PR has not been responded to for X amount of days label Jan 29, 2025
@AlexanderSehr AlexanderSehr changed the title [AVM Question/Feedback]: [AVM Question/Feedback]: RBAC Interface Jan 29, 2025
@AlexanderSehr AlexanderSehr self-assigned this Jan 29, 2025
@AlexanderSehr AlexanderSehr added Needs: Core Team 🧞 This item needs the AVM Core Team to review it and removed Needs: Triage 🔍 Maintainers need to triage still Status: Response Overdue 🚩 When an issue/PR has not been responded to for X amount of days labels Jan 29, 2025
@AlexanderSehr
Copy link
Contributor

Good day @Grant-Rc,
please excuse the late reply. General questions don't get an automatic (module) owner assigned which is why it takes a moment for them to pop up.
With this uplifiting intro out of the way, to your question:
The resource follows the general spec for RoleAssignments that is presribed for all AVM resource modules.
The idea: While the Bicep DSL does not yet allow users to provide anything but a role definition id for role assignments, we try to lessen that pain by hosting a subset of roles as a map (name => role definition id) in the modules.
While there is no hard requirement on which roles should and should not be part of a module, there is a general guidance that e.g., a key vault module should contain roles relevant for a key vault + some defaults like 'Contributor', 'Owner', etc.

Now, when using the module you have a few options how you can specify the role assignments:

roleAssignments: [
{
name: '3566ddd3-870d-4618-bd22-3d50915a21ef'
roleDefinitionIdOrName: 'Owner'
principalId: nestedDependencies.outputs.managedIdentityPrincipalId
principalType: 'ServicePrincipal'
}
{
name: guid('Custom seed ${namePrefix}${serviceShort}')
roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c'
principalId: nestedDependencies.outputs.managedIdentityPrincipalId
principalType: 'ServicePrincipal'
}
{
roleDefinitionIdOrName: subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'acdd72a7-3385-48ef-bd42-f606fba81ae7'
)
principalId: nestedDependencies.outputs.managedIdentityPrincipalId
principalType: 'ServicePrincipal'
}
]

In words:

  • You can provide the role name
  • You can provide the role definition GUID
  • You can provide the full role definition id

Processing this logic happens in the part you posted above

var formattedRoleAssignments = [
for (roleAssignment, index) in (roleAssignments ?? []): union(roleAssignment, {
roleDefinitionId: builtInRoleNames[?roleAssignment.roleDefinitionIdOrName] ?? (contains(
roleAssignment.roleDefinitionIdOrName,
'/providers/Microsoft.Authorization/roleDefinitions/'
)
? roleAssignment.roleDefinitionIdOrName
: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName))
})
]

All that being said - there's a catch. You will only be able to use the names of roles that have been implemented in the module - and you'll have a hard time knowing which roles are supported without looking at the code. In case of the resource group module these roles would be

var builtInRoleNames = {
Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
'Quota Request Operator': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'0e5f05e5-9ab9-446b-b98d-1e2157c94125'
)
Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
'Resource Policy Contributor': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'36243c78-bf99-498c-9df9-86d9f8d28608'
)
'Role Based Access Control Administrator': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'f58310d9-a9f6-439a-9e8d-f62e7b41a168'
)
'Tag Contributor': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'4a9ae827-6dc8-4573-8ac7-8239d42aa03f'
)
'Template Spec Contributor': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'1c9b6475-caf0-4164-b5a1-2142a7116f4b'
)
'Template Spec Reader': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'392ae280-861d-42bd-9ea5-08ee6d83b80e'
)
'User Access Administrator': subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
)
}

I guess we can both agree that this is not a great experience. We unfortunately cannot use an allowedSet to provide Linter support as this would make it impossible to provide any role but the ones implemented in the module (e.g., no custom roles) which only left us with one reasonably automatable alternative: Extracting that information and providing it via a module's readme. You can see it working e.g., here for the Key Vault.
For the resource group module in particular, this logic that extracts the role names unfortunately does not work (as of today). It's not the only one where this is the case, but the simple explanation is that, given its scope, it has a bit of a unique 'structure' for which the readme utility would need to implement a custom case. This unfortunately did not happen yet.

In general, I hope the above provided some context on how to use the inferface for most modules and why it is designed in the way it is. The good news is that the ARM PG is working on a feature that would make it possible to fetch role definition ids on the fly. I don't know 'when' this feature will come, but they did call it out in one of their recent community calls. Once it does, we can massively simplify our logic in the modules as most of what I described above is really nothing else than a 'patch' for a more fundamental language restriction.

@AlexanderSehr AlexanderSehr added the Needs: Author Feedback 👂 Awaiting feedback from the issue/PR author label Jan 29, 2025
@Grant-Rc
Copy link
Author

Hello @AlexanderSehr Thank you for the response and looking forward to the role definition id fetch.

Ill keep an eye on the updates, i was able to just the ID of the role I wanted with no issues hence just a question.

Thank you
@Grant-Rc

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 Reply has been added to issue, maintainer to review and removed Needs: Author Feedback 👂 Awaiting feedback from the issue/PR author labels Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Attention 👋 Reply has been added to issue, maintainer to review Needs: Core Team 🧞 This item needs the AVM Core Team to review it Type: AVM 🅰️ ✌️ Ⓜ️ This is an AVM related issue Type: Question/Feedback 🙋 Further information is requested or just some feedback
Projects
None yet
Development

No branches or pull requests

2 participants