In the last blog post, I kicked off a short series on Microsoft Graph for Bicep. Today’s second part is about further expanding the initial setup of Part 1 so that we can further integrate Bicep for Microsoft Graph into our existing automation in the future and replace some PowerShell steps.
Today we will take a closer look at how the created group can be used with and without Entra ID users for Azure RBAC role assignments, for example.
Example
As a basis we use the Github repository from Part 1 and build on it further.
Security Group with Azure RBAC permissions
The first example includes the creation of an Entra Security Group which is further used to set an Azure RBAC permission on a resource. In this example, a Log Analytics Workspace (LAW), which receives the permission using the security group.
extension microsoftGraphV1 @description('Name of the group to be created') param groupName string resource group 'Microsoft.Graph/[email protected]' = { displayName: groupName mailEnabled: false mailNickname: uniqueString(groupName) securityEnabled: true uniqueName: groupName } output groupId string = group.id output groupDisplayName string = group.displayName
logAnalyticsWorkspace.bicep
// Parameters @description('Name of the Log Analytics workspace.') param logAnalyticsWorkspaceName string @description('SKU name for the Log Analytics workspace.') @allowed([ 'Free' 'PerGB2018' ]) param logAnalyticsWorkspaceSkuName string @description('Log retention in days for the Log Analytics workspace.') param logAnalyticsWorkspaceRetentionInDays int @description('Maximum daily ingestion in gigabytes for the Log Analytics workspace.') param logAnalyticsWorkspaceDailyQuotaGb int @description('Name of the RBAC Role assignment.') param roleAssignmentName string @description('Principal ID of the user, group, or service principal to assign the role to.') param principalId string @description('Role definition ID to assign to the principal.') param roleDefinitionId string // Resources resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = { name: logAnalyticsWorkspaceName location: resourceGroup().location properties: { sku: { name: logAnalyticsWorkspaceSkuName } retentionInDays: logAnalyticsWorkspaceRetentionInDays workspaceCapping: { dailyQuotaGb: logAnalyticsWorkspaceDailyQuotaGb } } } resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: logAnalyticsWorkspace name: roleAssignmentName properties: { principalId: principalId roleDefinitionId: roleDefinitionId } }
main.bicep
// Extensions extension microsoftGraphV1 // Parameters @description('Name of the group to be created') param groupName string @description('Name of the Log Analytics workspace to be created') param logAnalyticsWorkspaceName string @description('Sku name of the Log Analytics workspace to be created') param logAnalyticsWorkspaceSkuName string @description('Retention period in days for the Log Analytics workspace') param logAnalyticsWorkspaceRetentionInDays int @description('Daily quota in GB for the Log Analytics workspace') param logAnalyticsWorkspaceDailyQuotaGb int @description('Role definition ID to assign to the principal.') param roleDefinitionId string // Variables @description('Name of the role assignment to be created') var roleAssignmentName = guid(groupName, roleDefinitionId, resourceGroup().id) // Resources module groups 'modules/groups.bicep' = { name: 'groups' params: { groupName: groupName } } module logAnalyticsWorkspace 'modules/logAnalyticsWorkspace.bicep' = { name: 'logAnalyticsWorkspace' params: { logAnalyticsWorkspaceName: logAnalyticsWorkspaceName logAnalyticsWorkspaceSkuName: logAnalyticsWorkspaceSkuName logAnalyticsWorkspaceRetentionInDays: logAnalyticsWorkspaceRetentionInDays logAnalyticsWorkspaceDailyQuotaGb: logAnalyticsWorkspaceDailyQuotaGb roleAssignmentName: roleAssignmentName principalId: groups.outputs.groupId roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) } } // Outputs output groupName string = groups.outputs.groupDisplayName output groupId string = groups.outputs.groupId output roleAssignmentName string = roleAssignmentName
main.bicepparam
using './main.bicep' param groupName = 'sg-con-log-prod-switzerlandnorth-01' param logAnalyticsWorkspaceName = 'con-log-prod-switzerlandnorth-01' param logAnalyticsWorkspaceSkuName = 'PerGB2018' param logAnalyticsWorkspaceRetentionInDays = 30 param logAnalyticsWorkspaceDailyQuotaGb = 1 param roleDefinitionId = '92aaf0da-9dab-42b6-94a3-d43ce8d16293' //Log Analytics Contributor
Result
After executing the bicep code, the security group, log analytics workspace and the defined Azure RBAC authorisation were set correctly.
The complete code of the new example can be found here: Github example: security-group-add-to-law
Security Group with Users and Azure RBAC permissions
The second example now not only includes the creation of the security group but also fills it with the users according to Part 1 and sets the Azure RBAC permission to the created Log Analytics Workspace.
users.bicep
// Extensions extension microsoftGraphV1 // Parameters @description('List of User Principal Names (UPNs)') param upnList array // Variables @description('Length of the UPN list') var upnListLength = length(upnList) // Resources resource userList 'Microsoft.Graph/[email protected]'existing = [for i in range(0, upnListLength): { userPrincipalName: upnList[i] }] // Output output userIds array = [for i in range(0, upnListLength): userList[i].id] output userPrincipalNames array = upnList
The users module is now added to main.bicep.
main.bicep
// Resources module users 'modules/users.bicep' = { name: 'users' params: { upnList: upnList } }
Result
After adding the users.bicep module and making adjustments to the main.bicep file, the security group is now also filled with the defined users, who then receive RBAC permissions for the Log Analytics workspace.
You can find the complete code here in my Github repository.
Conclusion
Once you have familiarised yourself with Microsoft Graph for Bicep, it becomes easier and easier to work with it and create new modules.
The principle or rather the structure is just as simple as, for example, Azure resource creation using Bicep.
With the help of what you have learnt, you should now be able to adapt some of your PowerShell scripts in the Microsoft Graph environment, for example, to Bicep.