Introduction

In this post we'll create a custom Azure IAM role to grant specific permissions to a user on an Azure App Service that allows them to perform two job-specific actions:

  1. View the deployment center logs so they can confirm that each deployment is successful.
  2. Restart the web application

As we grant these permissions via a custom IAM role, we'll hold back the ability to make configuration changes, and view other elements of the permission they don't need access to.

Creating a Custom Role

Custom roles can be created in Azure by describing the role and its permissions in a JSON format. The below JSON describes a custom role, which I'll save in a file called custom_webapp_publisher.json:

{
    "Name": "Custom WebApp Publisher",
    "Id": null,
    "IsCustom": true,
    "Description": "Allows users to read all web app details, deployment center logs, and restart web applications.",
    "Actions": [
        "Microsoft.Web/sites/restart/action",
	"Microsoft.Web/sites/publishxml/read",
        "Microsoft.Web/sites/containerlogs/action",
        "Microsoft.Web/sites/*/read"
    ],
    "NotActions": [],
    "AssignableScopes": [
	"/subscriptions/<subscription id>"
    ]
}

The following properties are important to know:

  • Name is simply a user-friendly name for the role. This will be used to grant and revoke the role.
  • Description is displayed in the Azure portal and via CLI.
  • Actions is a list of specific Azure permissions. In this case we'll allow site restart, a read permission to the Deployment Center, the ability to read the logs in the deployment center, and a general read permission so the user can view the site in the portal.
  • AssignableScopes serves to limit in what context this permission can be used. In this case the role is assignable to any web site in a single subscription.

Create the Custom Role

To create the role, I'll provide the json role definition to Azure using the `az` CLI:

az role definition create --role-definition custom_webapp_publisher.json

View the Custom Role

After running the role definition create command, I can check that the role exists, and view the detailed definition of the role:

az role definition list --custom-role-only true --output table
az role definition list --name "Custom WebApp Publisher" --output json

The second command will echo back JSON similar to what I used to define the role:

[
  {
    "assignableScopes": [
      "/subscriptions/************"
    ],
    "createdBy": "<my Entra UUID>",
    "createdOn": "2025-02-13T15:05:43.208467+00:00",
    "description": "Allows users to read all web app details, deployment center logs, and restart web applications.",
    "id": "/subscriptions/****/providers/Microsoft.Authorization/roleDefinitions/****",
    "name": "*****",
    "permissions": [
      {
        "actions": [
          "Microsoft.Web/sites/restart/action",
          "Microsoft.Web/sites/publishxml/read",
          "Microsoft.Web/sites/containerlogs/action",
          "Microsoft.Web/sites/*/read"
        ],
        "condition": null,
        "conditionVersion": null,
        "dataActions": [],
        "notActions": [],
        "notDataActions": []
      }
    ],
    "roleName": "Custom WebApp Publisher",
    "roleType": "CustomRole",
    "type": "Microsoft.Authorization/roleDefinitions",
    "updatedBy": "*****",
    "updatedOn": "2025-02-13T15:05:43.208467+00:00"
  }
]

Assign the Role

Now that the custom role exists, I can assign it to a user or security group for a specific web or function application:

az role assignment create `
  --assignee "<sec group UUID, user UUID or user email" `
  --role "Custom WebApp Publisher" `
  --scope "/subscriptions/<subscription UUID>/resourceGroups/<RG Name>/providers/Microsoft.Web/sites/<Web/Fn Site Name>"

If the user didn't have any access to the web site, now they will see it in the portal, be able to review the deployment logs, and restart the web app.

💡
We can use the Azure Portal GUI to assign and revoke roles if desired. I'm using CLI here only because that's my preference.

If I want more or fewer permissions, I can specify additional actions or remove actions as desired.

Check Role Assignments

To view the role assignments, use the az role assignment list CLI command:

az role assignment list --role "Custom WebApp Publisher" `
  --scope "/subscriptions/<sub uuid>/resourceGroups/<rg name>/providers/Microsoft.Web/sites/<site name>" `
  --include-groups `
  --include-inherited --output table 

Update the Role

If it's desired to add or remove permissions from the role, this is done by:

  1. Export the role JSON using the az role definition list command.
  2. Extract the JSON object for the role to modify from the exported JSON list , modify the JSON object to reflect the new role actions.
  3. Update the role using the az role definition update command.
az role definition list --name "Custom WebApp Publisher" `
   --output json > role.json
   
az role definition update --role-definition role.json

Revoke the Role

Similarly we can revoke the custom role through CLI (or Powershell or Portal). Here I'll use az CLI:

az role assignment delete `
  --assignee "<user email or UUID>" `
  --role "Custom WebApp Publisher" `
  --scope "/subscriptions/<subscription UUID>/resourceGroups/<RG Name>/providers/Microsoft.Web/sites/<Web/Fn Site Name>"

Delete the Custom IAM Role

Finally, if we no longer want to use the IAM Role, we can remove it from Azure.

az role definition delete --name "Custom WebApp Publisher"
💡
Note: a custom IAM Role cannot be removed if it has active assignments. Remove all assignments before deleting the role.