Azure Graph API - Approve PIM requests - azure

I'm trying to approve/deny requests for role activations using the new Azure AD Privileged Identity Management REST API.
I am already able to read all pending role activation requests using the following request:
GET https://graph.microsoft.com/beta/roleManagement/directory/roleAssignmentScheduleRequests
The response looks like this:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#roleManagement/directory/roleAssignmentScheduleRequests",
"value": [
{
"id": "40b1dff9-9703-4da8-bf8f-275141347b6e",
"status": "PendingApproval",
"createdDateTime": "2021-06-04T10:47:40.34Z",
"completedDateTime": "2021-06-04T10:47:40.15Z",
"approvalId": "40b1dff9-9703-4da8-bf8f-275141347b6e",
"customData": null,
"action": "SelfActivate",
"principalId": "049bad91-8812-4daa-870e-1edf05f5ced1",
"roleDefinitionId": "9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3",
"directoryScopeId": "/",
"appScopeId": null,
"isValidationOnly": false,
"targetScheduleId": "40b1dff9-9703-4da8-bf8f-275141347b6e",
"justification": "My custom reason",
"createdBy": {
"application": null,
"device": null,
"user": {
"displayName": null,
"id": "049bad91-8812-4daa-870e-1edf05f5ced1"
}
},
"scheduleInfo": {
"startDateTime": null,
"recurrence": null,
"expiration": {
"type": "afterDuration",
"endDateTime": null,
"duration": "PT8H"
}
},
"ticketInfo": {
"ticketNumber": "",
"ticketSystem": ""
}
}
]
}
Which matches the request I can see in the Azure Portal:
Now I am trying to approve the above request using the PATCH operation by providing the returned id:
PATCH https://graph.microsoft.com/beta/roleManagement/directory/roleAssignmentScheduleRequests/40b1dff9-9703-4da8-bf8f-275141347b6e
For the payload, I tried adding Provisioned and Denied:
{
"status": "Denied"
}
But for whatever reason, I keep getting the following Error (Code 404):
{
"error": {
"code": "UnknownError",
"message": "{\"message\":\"No HTTP resource was found that matches the request URI 'https://api.azrbac.mspim.azure.com/api/v3/roleManagement/directory/roleAssignmentScheduleRequests('40b1dff9-9703-4da8-bf8f-275141347b6e')?'.\"}",
"innerError": {
"date": "2021-06-04T11:06:18",
"request-id": "ec668ea0-cf33-4e41-bfb4-19ca4ac683ad",
"client-request-id": "ca765884-79b1-7695-5c72-c5783dd9968c"
}
}
}
Any ideas?

Finally, I was able to find a solution. Here is a complete sample using the PowerShell Graph SDK:
$scopes = #(
"PrivilegedAccess.Read.AzureAD",
"RoleAssignmentSchedule.ReadWrite.Directory",
"PrivilegedAccess.ReadWrite.AzureAD"
)
Connect-MgGraph -Scopes $scopes
[array]$pendingApprovals = Invoke-GraphRequest `
-Method GET `
-Uri '/beta/roleManagement/directory/roleAssignmentScheduleRequests?$filter=(status eq ''PendingApproval'')' |
Select-Object -ExpandProperty value
$approvalSteps = Invoke-GraphRequest `
-Method GET `
-Uri ('/beta/roleManagement/directory/roleAssignmentApprovals/{0}' -f $pendingApprovals[0].approvalId) |
Select-Object -ExpandProperty steps | Where-Object status -eq InProgress
$body = #{
reviewResult = 'Approve'
justification = 'Seems legit'
}
Invoke-GraphRequest `
-Method PATCH `
-Uri ('https://graph.microsoft.com/beta/roleManagement/directory/roleAssignmentApprovals/{0}/steps/{1}' -f $pendingApprovals[0].approvalId, $approvalSteps.id) `
-Body $body
I also wrote a blog article about it:
Approve requests for Azure AD roles in PIM

You are on the right track using roleAssignmentScheduleRequests to get the pending request. Check out the response and in the value array there is an ID. Use that ID in the Update privilegedapproval call. (https://learn.microsoft.com/en-us/graph/api/privilegedapproval-update?view=graph-rest-beta&tabs=http)
PATCH /privilegedApproval/{id}
Example using the IDs you shared:
PATCH https://graph.microsoft.com/beta/privilegedApproval/40b1dff9-9703-4da8-bf8f-275141347b6e
Content-type: application/json
Content-length: 180
{
"approvalState": "approved",
"approverReason": "Martin Brandl approves you!"
}
In the request body for approval state your possible values are: pending, approved, denied, aborted, canceled.

Related

How to rename and edit an item in a single change request - Azure devops pushes api

Using the Devops pushes endpoint like _apis/git/repositories/<Project>/pushes?api-version=6.0 we can rename or edit a file.
This is working no problem. However, I want to rename and edit a file in a single commit. I've tried passing two changes in a single request, like:
{
"changes": [
{
"changeType": "rename",
"item": {
"path": "/path/new-filename.txt"
},
"sourceServerItem": "/path/old-filename.txt"
},
{
"changeType": "edit",
"item": {
"path": "/path/new-filename.txt"
},
"newContent": {
"content": "...new content...",
"contentType": "rawtext"
}
}
]
}
This gave the error "Multiple operations were attempted on file 'path/new-filename.txt' within the same request. Only a single operation may be applied to each file within the same commit. Parameter name: newPush"
So I tried combining them with the change type of 'all'
{
"changeType": "all",
"item": {
"path": "/path/new-filename.txt",
},
"sourceServerItem": "/path/old-filename.txt",
"newContent": {
"content": "...new content...",
"contentType": "rawText"
}
}
Still no joy: "The parameters supplied are not valid. Parameter name: newPush"
Is this possible, or do I have to separate the changes in two commits?
Edit:
Can't even do this with multiple commits in one request 😭. I mean what's the point of having commits as an array when you must have exactly one commit anyway?
The parameters are incorrect. A posted push must contain exactly one commit and one refUpdate.
Parameter name: newPush
Test with the Rest API and I can reproduce the same situation.
The issue comes from the limitations of the Rest API itself. When we use the Rest API to do the push action, it limits that you can only make commit once and changes cannot be made to the same file at the same time.
You need to separate the changes in two commits.
To meet your requirement, you can use PowerShell Script to run the Rest API twice to commit the changes.
For example:
$token = "PAT"
$url="https://dev.azure.com/{Org}/{Project}/_apis/git/repositories/{Repo}/pushes?api-version=6.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$JSON = #'
{
"refUpdates": [
{
"name": "refs/heads/master",
"oldObjectId": "commitid"
}
],
"commits": [
{
"comment": "Renaming tasks.md to xxx",
"changes": [
{
"changeType": "rename",
"sourceServerItem": "/path/old-filename.txt",
"item": {
"path": "/path/new-filename.txt"
}
}
]
}
]
}
'#
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json
$newobjectid = $response.commits.commitid
echo $newobjectid
$JSON1 = "
{
`"refUpdates`": [
{
`"name`": `"refs/heads/master`",
`"oldObjectId`": `"$newobjectid`"
}
],
`"commits`": [
{
`"comment`": `"Renaming tasks.md to xxx`",
`"changes`": [
{
`"changeType`": `"edit`",
`"item`": {
`"path`": `"/path/new-filename.txt`"
},
`"newContent`": {
`"content`": `"...new content...`",
`"contentType`": `"rawtext`"
}
}
]
}
]
}
"
$response1 = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Post -Body $JSON1 -ContentType application/json

Interacting with AzureDevops using python

I am trying to achieve following things while interacting with AzureDevops using python:
To get the stories under Boards section
To get the branches under Repos section
I am able to establish connection to AzureDevops URL using requests API, but not sure how to read the data using it.
Is there any way by which I can do the same or if there is some other API using which I can do this?
Thanks in advance!!
Agree with Krzysztof Madej,
We could use write a WIQL query to list all User Story, you could refer this link for more details.
from vsts.vss_connection import VssConnection
from msrest.authentication import BasicAuthentication
import json
from vsts.work_item_tracking.v4_1.models.wiql import Wiql
def emit(msg, *args):
print(msg % args)
def print_work_item(work_item):
emit(
"{0} {1}: {2}".format(
work_item.fields["System.WorkItemType"],
work_item.id,
work_item.fields["System.Title"],
)
)
personal_access_token = 'YourPATToken'
organization_url = 'https://dev.azure.com/YourorgName'
# Create a connection to the org
credentials = BasicAuthentication('', personal_access_token)
connection = VssConnection(base_url=organization_url, creds=credentials)
wiql = Wiql(
query="""select [System.Id] From WorkItems """
)
wit_client = connection.get_client('vsts.work_item_tracking.v4_1.work_item_tracking_client.WorkItemTrackingClient')
wiql_results = wit_client.query_by_wiql(wiql).work_items
if wiql_results:
# WIQL query gives a WorkItemReference with ID only
# => we get the corresponding WorkItem from id
work_items = (
wit_client.get_work_item(int(res.id)) for res in wiql_results
)
for work_item in work_items:
print_work_item(work_item)
List all branches, we could use Refs - List and add variable filter to list all branches, If we do not add it, it will also list pull request.
Sample:
List all repo and get repo ID.
GET https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories?api-version=4.1
List repo branches via repo ID
GET https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=heads&api-version=4.1
Result:
Update1
Power shell script
#List all branches name
$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$BranchDetailURL = "https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=heads&?api-version=6.0"
$BranchInfo = Invoke-RestMethod -Uri $BranchDetailURL -Headers #{authorization = "Basic $base64AuthInfo"} -Method Get
Write-Host $BranchInfo.value.name
#List all User Story ID
$WorkItemWiqlQuery = "https://dev.azure.com/v-viliu/test_Agile/test/_apis/wit/wiql?api-version=5.1"
$query = "Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.WorkItemType] = 'User Story'"
$body = #{query=$query} | ConvertTo-Json
$WorkItemDetailInfo = Invoke-RestMethod -Uri $WorkItemWiqlQuery -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic $base64AuthInfo")} -Body $body
Write-Host $WorkItemDetailInfo.workItems.id
Result:
To get stories please check this answer but keep in mind to set proper filter [System.WorkItemType] = 'Task'".
To get branches you need to use Refs - List endpoint
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/refs?api-version=6.0
Sample response
{
"value": [
{
"name": "refs/heads/feature/calcApp",
"objectId": "ffe9cba521f00d7f60e322845072238635edb451",
"creator": {
"displayName": "Normal Paulk",
"url": "https://vssps.dev.azure.com/fabrikam/_apis/Identities/ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"_links": {
"avatar": {
"href": "https://dev.azure.com/fabrikam/_apis/GraphProfile/MemberAvatars/aad.YmFjMGYyZDctNDA3ZC03OGRhLTlhMjUtNmJhZjUwMWFjY2U5"
}
},
"id": "ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"uniqueName": "dev#mailserver.com",
"imageUrl": "https://dev.azure.com/fabrikam/_api/_common/identityImage?id=ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"descriptor": "aad.YmFjMGYyZDctNDA3ZC03OGRhLTlhMjUtNmJhZjUwMWFjY2U5"
},
"url": "https://dev.azure.com/fabrikam/7484f783-66a3-4f27-b7cd-6b08b0b077ed/_apis/git/repositories/d3d1760b-311c-4175-a726-20dfc6a7f885/refs?filter=heads%2Ffeature%2FcalcApp"
},
{
"name": "refs/heads/feature/replacer",
"objectId": "917131a709996c5cfe188c3b57e9a6ad90e8b85c",
"creator": {
"displayName": "Normal Paulk",
"url": "https://vssps.dev.azure.com/fabrikam/_apis/Identities/ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"_links": {
"avatar": {
"href": "https://dev.azure.com/fabrikam/_apis/GraphProfile/MemberAvatars/aad.YmFjMGYyZDctNDA3ZC03OGRhLTlhMjUtNmJhZjUwMWFjY2U5"
}
},
"id": "ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"uniqueName": "dev#mailserver.com",
"imageUrl": "https://dev.azure.com/fabrikam/_api/_common/identityImage?id=ac5aaba6-a66a-4e1d-b508-b060ec624fa9",
"descriptor": "aad.YmFjMGYyZDctNDA3ZC03OGRhLTlhMjUtNmJhZjUwMWFjY2U5"
},
"url": "https://dev.azure.com/fabrikam/7484f783-66a3-4f27-b7cd-6b08b0b077ed/_apis/git/repositories/d3d1760b-311c-4175-a726-20dfc6a7f885/refs?filter=heads%2Ffeature%2Freplacer"
},

Get all security groups and users associated with a certain build definition[Azure-Devops]

I have looked through the documentation available at -
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/?view=azure-devops-rest-5.1
For a certain build definition, I want to be able to get all the security groups and users associated with it through code/powershell script and output it to a json file for example.
Any help will be appreciated! I have tried curling multiple api's but not getting what I need.
Thanks!
There has one api does not been documented. Try with below:
POST https://dev.azure.com/{org name}/_apis/Contribution/HierarchyQuery/project/{project name}?api-version=5.0-preview.1
Request body:
{
"contributionIds": [
"ms.vss-admin-web.security-view-members-data-provider"
],
"dataProviderContext": {
"properties": {
"permissionSetId": "33344d9c-fc72-4d6f-aba5-fa317101a7e9",
"permissionSetToken": "{token}",
"sourcePage": {
"url": "https://dev.azure.com/{org name}/{project name}/_build?definitionId={build definition id}&_a=summary",
"routeId": "ms.vss-build-web.pipeline-details-route",
"routeValues": {
"project": "{project name}",
"viewname": "details",
"controller": "ContributedPage",
"action": "Execute",
"serviceHost": "{org name}"
}
}
}
}
}
Some key points you should pay attention to:
permissionSetId: Here the 33344d9c-fc72-4d6f-aba5-fa317101a7e9 is
a fixed value which represent the namespaceid of build security.
permissionSetToken: This is the token which can used to get the
security info. You can run below command to get the token(s) you
should used.
az devops security permission list --id
33344d9c-fc72-4d6f-aba5-fa317101a7e9 --subject {your account}
--output table --organization https://dev.azure.com/{org name} --project {project name}
url: Here the url value used to tell the system which specific
build you want to check. Just replace the corresponding org
name/project name/definition id into the URL sample provided.
In addition, I wrote a shot powershell script for you:
$token = "{token}"
$url="https://dev.azure.com/{org name}/_apis/Contribution/HierarchyQuery/project/{project name}?api-version=5.0-preview.1"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$context=#"
{
"contributionIds": [
"ms.vss-admin-web.security-view-members-data-provider"
],
"dataProviderContext": {
"properties": {
"permissionSetId": "33344d9c-fc72-4d6f-aba5-fa317101a7e9",
"permissionSetToken": "{token}",
"sourcePage": {
"url": "https://dev.azure.com/{org name}/{project name}/_build?definitionId={build definition id}&_a=summary",
"routeId": "ms.vss-build-web.pipeline-details-route",
"routeValues": {
"project": "{project name}",
"viewname": "details",
"controller": "ContributedPage",
"action": "Execute",
"serviceHost": "{org name}"
}
}
}
}
}
"#
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Post -Body $context -ContentType "application/json"
Write-Host "results = $($response.dataProviders.'ms.vss-admin-web.security-view-members-data-provider'.identities.displayname| ConvertTo-Json -Depth 100)"

how to create an azure function key in ARM template?

I have been struggling with this one all day, I am trying to create a Function App function key from an ARM template.
So far I have been able to create my function key on the Host level using the following template:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/default/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
then I found a couple of articles and link showing it is possible via API:
https://github.com/Azure/azure-functions-host/wiki/Key-management-API
And I was able to generate it via this API posting to:
https://{myfunctionapp}.azurewebsites.net/admin/functions/{MyFunctionName}/keys/{NewKeyName}?code={_masterKey}
But I can't for the sake of me figure out how to do that in my ARM template!
I have tried various combinations of type and name, for example:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/{myfunctionName}/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
or /functions/{myfunctionName}/PortalFunctionKey
as suggested in some articles, and i just can't get any to work, can't find much documentation on ARM Microsoft.Web/sites/host/functionKeys either.
Did anyone succeed to create a FUNCTION key (not host) in ARM template? I would gladly hear how you got there :)!
Basically:
Many thanks in advance,
Emmanuel
This might solve the problem now: https://learn.microsoft.com/en-us/azure/templates/microsoft.web/2020-06-01/sites/functions/keys
I was able to create a function key by passing an ARM template resource that looked like this:
{
"type": "Microsoft.Web/sites/functions/keys",
"apiVersion": "2020-06-01",
"name": "{Site Name}/{Function App Name}/{Key Name}",
"properties": {
"value": "(optional)-key-value-can-be-passed-here"
}
}
It seems that even if you don't have 'value' in the properties, then you have to at least pass an empty properties object.
To solve this problem , you could refer to this github issue. First issue and second issue, these issues all have the problem about how to get the function key in the ARM template.
For now the sample to get the key value as the below shows:
"properties": {
"contentType": "text/plain",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default/'),'2016-08-01').functionKeys.default]"
}
or with below to get the key object.
"functionkeys": {
"type": "object",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default'), '2018-11-01')]" }
}
You could have a try, hope this could help you.
So it is not possible to create a Function level Function key in ARM template at the moment.
I therefore created a feature request you can vote on if you are interested in it:
https://feedback.azure.com/forums/169385-web-apps/suggestions/39789043-create-function-level-keys-for-azure-functions-in
For now though, we are creating function level function keys via a powershell deployment task step. here is how.
add output parameter to your ARM template:
"outputs": {
"masterKey": {
"type": "string",
"value": "[listkeys(concat(resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('appServiceName')), '/host/default'), '2018-11-01').masterKey]"
},
"appServiceName": {
"type": "string",
"value": "[parameters('appServiceName')]"
},
"functionKeys": {
"type": "array",
"value": [
{
"functionName": "myFunctionName",
"keys": [ "FunctionKeyName1", "FunctionKeyName2" ]
}
]
}
}
Add the following PS script file to your deploy project:
param (
[Parameter(Mandatory=$true)]
[string]
$armOutputString
)
Write-Host $armOutputString
$armOutputObj = $armOutputString | convertfrom-json
Write-Host $armOutputObj
$masterKey = $armOutputObj.masterKey.value
$appServiceName = $armOutputObj.appServiceName.value
$httpHeaders = #{
"x-functions-key" = $masterKey
}
$contentType = "application/json; charset=utf-8"
foreach($function in $armOutputObj.functionKeys.value){
$retryCount = 5;
while ($true) {
try {
$uriBase = "https://$($appServiceName).azurewebsites.net/admin/functions/$($function.functionName)/keys"
$existingKeys = Invoke-RestMethod -Method Get -Uri $uriBase -Headers $httpHeaders -ContentType $contentType
break;
}
catch {
if ($_.Exception.Response.StatusCode.value__ -eq 502) {
if ($retryCount-- -eq 0) {
throw;
}
else {
Write-Output ("Retry" + ": " + $_.Exception.Response.StatusCode + "; attempts=$retryCount")
[System.Threading.Thread]::Sleep(1000);
continue;
}
}
else {
throw;
}
}
}
foreach ($keyname in $function.keys){
$keyExists = 0
foreach($exstingKey in $existingKeys.keys){
if($exstingKey.name -eq $keyname){
$keyExists = 1
Write-Host "key $($keyname) already exists"
}
}
if($keyExists -eq 0){
$uri = "$($uriBase)/$($keyname)?code=$($masterKey)";
Write-Host "Adding $($keyname) key"
Invoke-RestMethod -Method Post -Uri "$($uriBase)/$($keyname)" -Headers $httpHeaders -ContentType $contentType;
}
}
}
The script ensures that the key will not be overwritten if it already exists, and will retry if it fails (the function MUST exist and be running for the API to work).
In your "Azure resource group deployment" task, under "Advanced" set "Deployment outputs" to "armDeployOutput".
Add a Powershell task, your script path to the powershell file in your deploy project, and set "Arguments" as "-armOutputString '$(armDeployOutput)'".
And that's it.

Azure Create Alert via API

Creating Alert via API in Azure.
Alert does get created but the Event Category field is showing as all instead of Administrative.
Alert i want to create is for Administrative Event Category but it is getting created for all Event Category.
I had used the same code earlier and it was working.
Azure Alert ScreenShot
If i try to update anything via GUI it gives an error: Failed to update alert 'Testing'.The category field is missing in the condition..
Error ScreenShot
PowerShell
Body to create Alert
$Remediate = #" {
"id": "/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxxxxx/providers/microsoft.insights/activityLogAlerts/Testing",
"type": "Microsoft.Insights/ActivityLogAlerts",
"name": "Testing",
"location": "Global",
"kind": null,
"tags": {},
"properties": {
"scopes": ["/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
"condition": {
"allOf": [{
"field": "Category",
"equals": "Administrative",
"containsAny": null
}, {
"field": "operationName",
"equals": "Microsoft.Authorization/policyAssignments/write",
"containsAny": null
}]
},
"actions": {
"actionGroups": [{
"actionGroupId": "/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/resourcegroups/xxxxxxxxxxxxxxx/providers/microsoft.insights/actiongroups/TestingAlertGRP",
"webhookProperties": ""
}]
},
"enabled": true,
"description": "Alert created for Testing"
},
"identity": null
}
"#
API
$API = "https://management.azure.com/subscriptions/$SubscriptionID/resourceGroups/$ResourceGroupName/providers/microsoft.insights/activityLogAlerts/$Name`?api-version=2017-04-01"
Invoke-RestMethod -Method Put -Uri $API -Headers #{Authorization = "Bearer $Token"} -Body $Remediate -ContentType 'application/json' | Out-Null
Note: You must specify at least one (Administrative, Security, Service Health, Recommendation, Policy, Autoscale) of the preceding criteria in your alert. You may not create an alert that activates every time an event is created in the activity logs.
For more details, refer “Create activity log alerts (Classic)”.
Alert does get created but the Event Category field is showing as all instead of Administrative.
Not to reproduce this issue, I check the request body, it should be fine.
If i try to update anything via GUI it gives an error: Failed to update alert 'Testing'.The category field is missing in the condition
I have reproduced this issue when the Event category is all(I modify the category to all via the API mentioned below).
If you want to fix the issue, I recommend you to use this API. Just click the Try It in the page and login your account. You could refer to the screenshot and my sample request body.
My sample request body:
{"location":"global","properties":{"scopes":["/subscriptions/xxxxxxx"],"description":"test","condition":{"allOf":[{"field":"category","equals":"Administrative"},{"field":"resourceType","equals":"Microsoft.Web/serverFarms"}]},"actions":{"actionGroups":[{"actionGroupId":"/subscriptions/xxxxxxx/resourcegroups/joywebapp/providers/microsoft.insights/actiongroups/joyactiongroup","webhookProperties":{}}]},"enabled":true}}
Request:
Check in the portal:

Resources