Reputation: 19925
I'm using Terraform to create app registration and roles for our apps. But I cannot figure out how to do the same with Bicep. This is what's used today:
Step 1. Register the app in Active Directory, effectively creating an "app registration".
resource "azuread_application" "ad_app" {
name = local.full_app_name
type = "webapp/api"
owners = var.app_owners
}
Step 2: Create a role for our app
resource "azuread_application_app_role" "person_read" {
application_object_id = azuread_application.ad_app.id
allowed_member_types = ["Application"]
description = "Person Reader can search and read persons"
display_name = "Person Reader"
value = "Persons.Read"
}
Problem is I cannot figure out how to do those steps with Bicep (or ARM templates). I tried with 'Microsoft.Authorization/roleDefinitions'
, but it doesn't seem right. And I have no idea about how to do the app registration.
Upvotes: 18
Views: 15822
Reputation: 29736
This is now possible using the Microsoft Graph Resource Provider (see documentation).
bicepconfig.json
config file:{
"experimentalFeaturesEnabled": {
"extensibility": true
}
}
Then you can create an application and app roles like this:
extension microsoftGraph
resource application 'Microsoft.Graph/applications@beta' = {
displayName: 'My fisrt application'
uniqueName: 'my-uniquename'
appRoles: [
{
id: guid('my-uniquename', 'Persons.Read') // need unique guid with same value foir each deployment
isEnabled: true
displayName: 'Person Reader'
description: 'Person Reader can search and read persons'
value: 'Persons.Read'
allowedMemberTypes: [
'Application'
]
}
]
}
Upvotes: 6
Reputation: 11451
Unfortunately both are not directly supported in ARM template or Bicep. But You can use Deployment Scripts to create both using Bicep/ARM template.
Create Azure AD App registration using Bicep:
param name string
param location string = resourceGroup().location
param currentTime string = utcNow()
resource script 'Microsoft.Resources/deploymentScripts@2019-10-01-preview' = {
name: name
location: location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${resourceId('app-reg-automation', 'Microsoft.ManagedIdentity/userAssignedIdentities', 'AppRegCreator')}': {}
}
}
properties: {
azPowerShellVersion: '5.0'
arguments: '-resourceName "${name}"'
scriptContent: '''
param([string] $resourceName)
$token = (Get-AzAccessToken -ResourceUrl https://graph.microsoft.com).Token
$headers = @{'Content-Type' = 'application/json'; 'Authorization' = 'Bearer ' + $token}
$template = @{
displayName = $resourceName
requiredResourceAccess = @(
@{
resourceAppId = "00000003-0000-0000-c000-000000000000"
resourceAccess = @(
@{
id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"
type = "Scope"
}
)
}
)
signInAudience = "AzureADMyOrg"
}
// Upsert App registration
$app = (Invoke-RestMethod -Method Get -Headers $headers -Uri "https://graph.microsoft.com/beta/applications?filter=displayName eq '$($resourceName)'").value
$principal = @{}
if ($app) {
$ignore = Invoke-RestMethod -Method Patch -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)" -Body ($template | ConvertTo-Json -Depth 10)
$principal = (Invoke-RestMethod -Method Get -Headers $headers -Uri "https://graph.microsoft.com/beta/servicePrincipals?filter=appId eq '$($app.appId)'").value
} else {
$app = (Invoke-RestMethod -Method Post -Headers $headers -Uri "https://graph.microsoft.com/beta/applications" -Body ($template | ConvertTo-Json -Depth 10))
$principal = Invoke-RestMethod -Method POST -Headers $headers -Uri "https://graph.microsoft.com/beta/servicePrincipals" -Body (@{ "appId" = $app.appId } | ConvertTo-Json)
}
// Creating client secret
$app = (Invoke-RestMethod -Method Get -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)")
foreach ($password in $app.passwordCredentials) {
Write-Host "Deleting secret with id: $($password.keyId)"
$body = @{
"keyId" = $password.keyId
}
$ignore = Invoke-RestMethod -Method POST -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)/removePassword" -Body ($body | ConvertTo-Json)
}
$body = @{
"passwordCredential" = @{
"displayName"= "Client Secret"
}
}
$secret = (Invoke-RestMethod -Method POST -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)/addPassword" -Body ($body | ConvertTo-Json)).secretText
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['objectId'] = $app.id
$DeploymentScriptOutputs['clientId'] = $app.appId
$DeploymentScriptOutputs['clientSecret'] = $secret
$DeploymentScriptOutputs['principalId'] = $principal.id
// create app role
'''
cleanupPreference: 'OnSuccess'
retentionInterval: 'P1D'
forceUpdateTag: currentTime // ensures script will run every time
}
}
output objectId string = script.properties.outputs.objectId
output clientId string = script.properties.outputs.clientId
output clientSecret string = script.properties.outputs.clientSecret
output principalId string = script.properties.outputs.principalId
Reference:
Creating App Registration with ARM templates/Bicep | by Jon Reginbald
Creating a App Roles for Azure AD application:
I don't have much idea on this but I guess you can use the below script where //create app role
is written in the above code:
$app = (Invoke-RestMethod -Method Get -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)")
$body1 = @{
Id = [Guid]::NewGuid().ToString()
IsEnabled = true
AllowedMemberTypes =@("application")
Description = "My Role Description.."
DisplayName = "My Custom Role"
Value = "MyCustomRole"
}
$createapprole= Invoke-RestMethod -Method POST -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)/appRoles" -Body ($body1 | ConvertTo-Json)
Reference:
Upvotes: 16