Create Entra ID Resources With Bicep

Ever since the release of ARM, and now Bicep, there has been a glaring omission from what we can create with this infrastructure as code languages - Entra ID (formally Azure AD) resources. There was an obvious reason for this, as Entra ID resources are created using the Graph API, which is a completely separate API from ARM. This has meant that we’ve had to resort to other methods for creating Entra ID resources as part of our deployments, things like deployment scripts or separate tasks in a pipeline. With the preview of the Azure Graph Extension for Bicep, we can now create some of these resources using Bicep!

Entra ID Extension


Before we dig into how this works, there are a few limitations you should be aware of:

  • This is in preview currently, so it’s not ready for production use and has all the usual limitations of a preview resource
  • The extension supports a limited number of resources, which are listed below, Notably, it doesn’t support the creation of AAD users. I imagine this will come in the future, but currently, it supports:
    • Applications
    • Groups
    • Service Principals
    • OAuth2 Permission Grants
    • App Role Assigned To
  • There are some known issues with the extension, which you can find documented here


To be able to deploy Graph resources, the account you use to run your deployment needs to be granted permission to be able to create these resources. This is using Entra ID permissions, which are separate from any Azure RBAC permissions. There are two ways you can do this:

  • If you’re using an interactive user, so deploying using your account via the CLI or similar then you can follow the steps here
  • If you’re using a service principal or managed identity to run your deployment non-interactively then follow the steps here

Whichever method you use, the account you deploy with needs to have enough rights to create, update and delete the resources you are looking at.


First, you need (other than the permissions mentioned above) to update your Bicep CLI and VS Code extension (if you are using it).

Secondly, we need to enable the extensibility feature, which is in preview currently. To do this, you need to create a bicepconfig.json file in the root of your project, or if you already have one then amend it. The file should contain the settings below:

    "experimentalFeaturesEnabled": {
        "extensibility": true

Creating Graph Resources

To demonstrate using the Graph extension we’ll create an Entra ID app and a group, and put the App in the group.

First things, we need to import the provider into our main.bicep file.

provider microsoftGraphwqed

First, we’ll create the Entra ID application, we’re just using the required values to create this, but you can customise this as much as you need.

resource demoApp 'Microsoft.Graph/applications@v1.0' = {
  displayName: 'demoApp'
  signInAudience: 'AzureADMyOrg'
  uniqueName: 'demoApp'

Next, we’ll create a Service Principle (or Enterprise App) for the application, as this is what will be added to the group. It needs to reference the app, and have the same display name.

resource demoSp 'Microsoft.Graph/servicePrincipals@v1.0' = {
  displayName: 'demoApp'
  appId: demoApp.appId 

Finally, we create the group. Again, we’ll just provide the required values for the group here, there are more options if you need to customise it further. We’ll add the application we created to this group and make it an owner.

resource demoGroup 'Microsoft.Graph/groups@v1.0' ={
  displayName: 'demoGroup'
  mailEnabled: false
  securityEnabled: true
  uniqueName: 'demoGroup'
  mailNickname: 'demoGroup' 
  owners: [
  members: [

A couple of things to note here with the group:

  • We have to supply mailNickname, even if the group is not mail-enabled
  • There does not seem to be a way yet to add a user or app to a group outside of when it is created, you can’t reference an existing group and add your app.

We can go ahead and deploy this, this is done in the same way as deploying any other resource. Note that if you’re using the default resource group scoped deployment, you will need to create a resource group to run the deployment against, even if all you are doing is creating Entra ID resources, which don’t need the resource group.


The Entra ID extension for Bicep is a great start for closing a hole in Bicep that’s been there a long time. Commonly, a deployment needs to create Entra ID resources and this extension means we can start to migrate this into our Bicep resources. However, the current extension is a bit limited, both in the resources it covers and the operations supported on the resources. This is the first release of this extension, so hopefully we will see it expanded soon to cover all resources and extensions we need.