Share via


Quickstart: Deploy a Bicep file as a service principal

This quickstart guides you to deploy a Bicep file with Microsoft Graph resources using app-only authentication (noninteractive authentication). This approach enables seamless integration into CI/CD pipelines for zero-touch deployments.

For delegated or interactive authentication, see Create a Bicep file with Microsoft Graph resources.

Prerequisites

Create a service principal and assign an Azure role

Sign in to Azure CLI and create a service principal for deploying the Bicep file.

This example uses an application password (client secret) for simplicity and testing only. Assign the service principal the Managed Identity Contributor role scoped to a resource group.

Caution

Avoid using application passwords in production environments.

# Create a resource group
az group create --name exampleRG --location eastus

# Create a service principal with the Managed Identity Contributor role. Replace {myServicePrincipalName}, {mySubscriptionId}, and {myResourceGroupName} with your values.
az ad sp create-for-rbac --name {myServicePrincipalName} --role "Managed Identity Contributor" --scopes "/subscriptions/{mySubscriptionId}/resourceGroups/{myResourceGroupName}"

Output:

{
  "appId": "myServicePrincipalId",
  "displayName": "myServicePrincipalName",
  "password": "myServicePrincipalPassword",
  "tenant": "myOrganizationTenantId"
}

Copy the password value — it can't be retrieved later.

Assign Microsoft Graph permissions to the service principal

Grant the Group.ReadWrite.All application-only permission to the service principal using Microsoft Graph PowerShell. The Privileged Role Administrator role allows you to assign the required AppRoleAssignment.ReadWrite.All and Application.Read.All permissions.

Caution

Limit access to apps granted the AppRoleAssignment.ReadWrite.All permission. See AppRoleAssignment.ReadWrite.All for details.

# Authenticate to Microsoft Graph
Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All","Application.Read.All"

# Find the service principal created earlier
$mySP = Get-MgServicePrincipalByAppId -AppId "myServicePrincipalId"

# Find the Microsoft Graph service principal
$graphSP = Get-MgServicePrincipalByAppId -AppId "00000003-0000-0000-c000-000000000000"

# Assign Group.ReadWrite.All app-only permission
New-MgServicePrincipalAppRoleAssignedTo -ResourceId $graphSP.Id -ServicePrincipalId $graphSP.Id -PrincipalId $mySP.Id -AppRoleId "62a82d76-70ea-41e2-9197-370581804d09"

Sign in as service principal to deploy the Bicep file

Sign in using the service principal created earlier.

# Sign in with the service principal. This sample uses the Bash console.
spID=$(az ad sp list --display-name myServicePrincipalName --query "[].{spID:appId}" --output tsv)
tenantID=$(az ad sp list --display-name myServicePrincipalName --query "[].{tenantID:appOwnerOrganizationId}" --output tsv)
echo "Using appId $spID in tenant $tenantID"

az login --service-principal --username $spID --password {paste your SP password here} --tenant $tenantID

Important

To avoid displaying your password on console when using az login interactively, use the read -s command in bash.

read -sp "Azure password: " AZ_PASS && echo && az login --service-principal -u <app-id> -p $AZ_PASS --tenant <tenant>

Deploy the Bicep file

Deploy the Bicep file using the resource group's scope.

az deployment group create --resource-group exampleRG --template-file main.bicep

Note

Deployment may fail due to replication delays when adding the managed service identity (MSI) as an owner of the Microsoft Entra group. Wait and retry the deployment.

Clean up resources

Use Azure CLI or Azure PowerShell to delete the Azure resources and Microsoft Graph resources when no longer needed.

Note

Resource groups are an Azure concept and have no effect on Microsoft Graph resources. Microsoft Graph resources need to be cleaned up with another request to Microsoft Graph. For this you can use Azure CLI or Azure PowerShell, or Microsoft Graph PowerShell.

The following examples show commands to delete the Azure resource first then the Microsoft Graph resources using Azure CLI and Azure PowerShell.

# Delete the resource group
az group delete --name exampleRG

# Delete the Microsoft Graph group
az rest --method delete --url 'https://graph.microsoft.com/v1.0/groups%28uniqueName=%27myExampleGroup%27%29'

# Delete the client service principal
spID=$(az ad sp list --display-name myServicePrincipalName --query "[].{spID:id}" --output tsv)
az ad sp delete --id $spID