> For the complete documentation index, see [llms.txt](https://docs.p0.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.p0.dev/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/create-a-custom-role.md).

# Create a custom role

When the [built-in Azure roles](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles) don't fit your needs, you can create a custom role and point P0's **Standard user role id** or **Admin user role id** field at it. This guide creates that custom role with the Azure CLI or Terraform.

The steps create the **standard user role**, which grants the permissions needed to reach VMs through a jump host or bastion host over Azure IAM. To create the **admin user role**, which adds sudo access on the target VM, give the role a distinct name and add the admin data action noted in each step.

{% hint style="info" %}
P0 recommends two built-in roles you can use instead of a custom role: **Virtual Machine User Login** (`fb879df8-f326-4884-b1cf-06f3ad86be52`) for standard access and **Virtual Machine Administrator Login** (`1c0163c0-47e6-4577-8991-ea5c82e286e4`) for admin access. Create a custom role only when neither built-in role fits your needs.
{% endhint %}

## Prerequisites

* Permission to create custom roles in the subscription, such as the built-in **User Access Administrator** or **Owner** role.
* The **Azure CLI** or **Terraform** installed, depending on which tool you use. See the [Azure CLI installation guide](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) or the [Terraform installation guide](https://developer.hashicorp.com/terraform/install).
* Your Azure **subscription ID**.

## Permissions granted

The role grants the following permissions. The read actions let the connecting user resolve the jump host and target VM network configuration. The data actions let the user sign in to the VM through the Azure AD login for Linux extension.

| Permission                                              | Type        | Purpose                                                                           |
| ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------- |
| `Microsoft.Network/publicIPAddresses/read`              | Action      | Resolve public IP addresses                                                       |
| `Microsoft.Network/virtualNetworks/read`                | Action      | Resolve virtual network configuration                                             |
| `Microsoft.Network/loadBalancers/read`                  | Action      | Resolve load balancer configuration                                               |
| `Microsoft.Network/networkInterfaces/read`              | Action      | Resolve network interface configuration                                           |
| `Microsoft.Compute/virtualMachines/*/read`              | Action      | Read virtual machine configuration                                                |
| `Microsoft.Compute/virtualMachines/login/action`        | Data action | Sign in to the VM as a standard user                                              |
| `Microsoft.Compute/virtualMachines/loginAsAdmin/action` | Data action | Sign in to the VM as an administrator with sudo privileges (admin user role only) |

## Create the role

{% tabs %}
{% tab title="Azure CLI" %}

1. Save the role definition to a file named `standard-user-role.json`. Replace `{subscriptionId}` with your subscription ID:

   ```json
   {
     "Name": "P0 VM Standard Login",
     "IsCustom": true,
     "Description": "Standard access to VMs reached through the P0 jump host.",
     "Actions": [
       "Microsoft.Network/publicIPAddresses/read",
       "Microsoft.Network/virtualNetworks/read",
       "Microsoft.Network/loadBalancers/read",
       "Microsoft.Network/networkInterfaces/read",
       "Microsoft.Compute/virtualMachines/*/read"
     ],
     "NotActions": [],
     "DataActions": [
       "Microsoft.Compute/virtualMachines/login/action"
     ],
     "NotDataActions": [],
     "AssignableScopes": [
       "/subscriptions/{subscriptionId}"
     ]
   }
   ```

   To create the admin user role instead, change `Name` to a distinct value and add `"Microsoft.Compute/virtualMachines/loginAsAdmin/action"` to `DataActions`.
2. Create the role:

   ```bash
   az role definition create --role-definition standard-user-role.json
   ```
3. Retrieve the role definition ID:

   ```bash
   az role definition list --name "P0 VM Standard Login" --query "[0].id" --output tsv
   ```

   The command returns an ID in the format `/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{guid}`. This value is the role definition ID you enter in P0.
   {% endtab %}

{% tab title="Terraform" %}

1. Declare an `azurerm_role_definition` resource. Set `subscription_id` to your subscription ID:

   ```terraform
   resource "azurerm_role_definition" "p0_vm_standard_login" {
     name        = "P0 VM Standard Login"
     scope       = "/subscriptions/${var.subscription_id}"
     description = "Standard access to VMs reached through the P0 jump host."

     permissions {
       actions = [
         "Microsoft.Network/publicIPAddresses/read",
         "Microsoft.Network/virtualNetworks/read",
         "Microsoft.Network/loadBalancers/read",
         "Microsoft.Network/networkInterfaces/read",
         "Microsoft.Compute/virtualMachines/*/read",
       ]
       data_actions = [
         "Microsoft.Compute/virtualMachines/login/action",
       ]
     }

     assignable_scopes = [
       "/subscriptions/${var.subscription_id}",
     ]
   }

   output "standard_user_role_id" {
     value = azurerm_role_definition.p0_vm_standard_login.role_definition_resource_id
   }
   ```

   To create the admin user role instead, use a distinct resource name and role `name`, and add `"Microsoft.Compute/virtualMachines/loginAsAdmin/action"` to `data_actions`.
2. Apply the configuration:

   ```bash
   terraform init
   terraform apply
   ```

   The `standard_user_role_id` output holds the role definition ID, in the format `/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{guid}`. This value is the role definition ID you enter in P0.
   {% endtab %}
   {% endtabs %}

## Next step

Enter the role definition ID in the appropriate P0 field:

* For a custom jump host, see [Custom jump host](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/custom-jump-host.md#permissions).
* For an Azure bastion host, see [Azure bastion host](/integrations/resource-integrations/microsoft-azure/configure-bastion-host-integration/azure-bastion-host.md#setup-steps).
