Azure PIM for VM Admin Role - azure

I am new to Azure PIM and exploring its capabilities.
I have a use case in hand wherein I need to make the VM Admin role requestable via PIM. I am trying to build a custom role so that I can attach a single VM in the role as part of scope but am unable to do so. All the VMs that are present in the subscription/resource group are getting attached to the role which is not the requirement.
So, in short, is it possible to create a custom role with scope defined for a single VM only though there are multiple VM's in the subscription and(or) resource group.

Yes. You could do that with Az PowerShell cmdlet New-AzRoleDefinition.
Please refer to second example here. (Modify $subs = '/subscriptions/{subscription_id}/resourceGroups/{resourceGroup_name}/providers/Microsoft.Compute/virtualMachines/{VM_name}')
$role = [Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition]::new()
$role.Name = 'Virtual Machine Operator 2'
$role.Description = 'Can monitor and restart virtual machines.'
$role.IsCustom = $true
$perms = 'Microsoft.Storage/*/read','Microsoft.Network/*/read','Microsoft.Compute/*/read'
$perms += 'Microsoft.Compute/virtualMachines/start/action','Microsoft.Compute/virtualMachines/restart/action'
$perms += 'Microsoft.Authorization/*/read'
$perms += 'Microsoft.ResourceHealth/availabilityStatuses/read'
$perms += 'Microsoft.Resources/subscriptions/resourceGroups/read'
$perms += 'Microsoft.Insights/alertRules/*','Microsoft.Support/*'
$role.Actions = $perms
$role.NotActions = (Get-AzRoleDefinition -Name 'Virtual Machine Contributor').NotActions
$subs = '/subscriptions/{subscription_id}/resourceGroups/{resourceGroup_name}/providers/Microsoft.Compute/virtualMachines/{VM_name}'
$role.AssignableScopes = $subs
New-AzRoleDefinition -Role $role
Then you can assign this custom role to users in Azure Portal -> this VM -> Access control (IAM).
You can also use cmdlet New-AzRoleAssignment to assign the role.
New-AzRoleAssignment -ObjectId {objectID of the user} -RoleDefinitionName 'Virtual Machine Operator 2' -Scope /subscriptions/{subscription_id}/resourceGroups/{resourceGroup_name}/providers/Microsoft.Compute/virtualMachines/{VM_name}
Make sure the value of -Scope here is the same as AssignableScopes in the first script.
BTW:
In fact, I don't think it's necessary to attach a single VM in the role as part of scope.
When you assign the role to a user, you need to specify the scope as the second script above shown. You can create the custom role with all the VMs that are present in the subscription/resource group getting attached. When you assign the role, you specify only one particular VM as the scope. Then the user can only manage this VM, but not any other VMs.

Related

Get all role assignments of an Azure AD Principal

I have an Azure environment with multiple subscriptions and resources. My requirement is to have a functionality where if I pass a user name or SPN name, it gives me all azure resources (from management group to azure resource) where that user/spn has access to and what access it is (reader/ data reader etc).
Major catch is - I want PIM role assignments too. Is there a way to get it?
Options explored
https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments but this gives role assignments per scope. I want per user/spn
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-list-portal it does not cover PIM assignments and gives assignments per subscription only
Azure Resource Graph Explorer - this does not cover role assignments at all
Apart from iterating through 50 subscriptions, fetching role assignments per scope and then comparing object id, is there any better way?
You can use the below Powershell Script to get the role-assignement for a Service Principal Name in multiple Subscriptions.
Connect-AzAccount
$tenantID = "yourTenantID"
$spn = "serviceprincipalname"
$user= Get-AzADUser -UserPrincipalName $spn
$subscriptions = Get-AzSubscription -TenantId $tenantID
#$subscriptions.Id
foreach ($subscription in $subscriptions) {
$set = Set-AzContext -Subscription $subscription
$set
$roleassignment= Get-AzRoleAssignment -ObjectId $user.Id
$roleassignment
}
Output:
Reference:
Install the Azure Az PowerShell module | Microsoft Docs
This might help you:
az role assignment list --all --assignee <Pricipal_ID>
https://learn.microsoft.com/en-us/cli/azure/role/assignment?view=azure-cli-latest#az-role-assignment-list
#Gjoshevski has shared a useful command, but you still need to loop through each subscription to list the role assignments on each subscription (if you have more than one in your tenant).
The following Azure CLI commands will do the job.
spID='<ObjectID here>' # ObjectID of an Applicatin or Service Principal
$tenantId='<TenantID here>'
az login --tenant 'Your Tenant'
$sub_ids=$(az account list --query id -o tsv)
foreach ($sub_id in $sub_ids) {
az account set --subscription $sub_id
"Subscription Name: $(az account show --query name)"
az role assignment list --all --assignee $spID --include-inherited --include-groups -o table
}
Note that the above is PowerShell syntax but is using Aure CLI commands

Problems with assigning a Azure policy and multiple subscriptions

I'm having some issues assigning one of the built-in policies with a logAnalytics parameter where there are multiple subscriptions involved. I need to do it with code. Here's how I try to accomplish it.
Get a reference to the built-in policy definition to assign
$definition = Get-AzPolicyDefinition | Where-Object { $_.Properties.DisplayName -eq 'Deploy Log Analytics agent for Windows VMs' }
$parameter = #{
logAnalytics = '<resourceId to my logAnalytics workspace>'
}
Create the policy assignment with the built-in definition against your resource group
New-AzPolicyAssignment -Name 'Deploy LA Agent Windows VMs' -DisplayName 'Deploy LA Agent Windows VMs' -Scope "/subscriptions/<my subscriptionId" -PolicyDefinition $definition -AssignIdentity -Location 'norwayeast' -PolicyParameterObject $parameter
This code works fine if I assign the policy to the same subscription where the logAnalytics workspace is located, but if I scope the policy assignment to another subscription and afterward check the assignment in the portal, the Log Analytics Workspace parameter will be empty.
The service principal that runs these commands is owner of both subscriptions.
The most straight-forward way of applying policies across multiple subscriptions is to make them part of a management group. You can apply a policy to the management group and every subscription which is a member will inherit it.
Further information on management groups can be found here:
https://learn.microsoft.com/en-us/azure/governance/management-groups/overview
Amended code using management groups:
New-AzPolicyAssignment -Name 'Deploy LA Agent Windows VMs' -DisplayName 'Deploy LA Agent Windows VMs' -Scope "/providers/Microsoft.Management/managementGroups/managementGroup001" -PolicyDefinition $definition -AssignIdentity -Location 'norwayeast' -PolicyParameterObject $parameter
Notes
You will need to create a management group and add subscription(s) to it before running any commands.
Assigning subscription(s) to an existing management group can have adverse effects, check there are no conflicts.
An error is likely to be generated regarding the length of the names used as they are restricted to 24 characters. You should shorten or abbreviate them.
I have not tested this code so please double-check by reviewing the documentation on Microsoft's site before running in your own environment.

'this.Client.SubscriptionId' cannot be null

We noticed that our Azure Subscription field is empty eg:
Get-AzContext -ListAvailable
Name Account SubscriptionName Environment TenantId
---- ------- ---------------- ----------- --------
kk89gan-db99-41c8-95c4-d43adfdfaf34ad ... mymy#outlook.zzz ... AzureCloud 674ce2a1-d4sd1da..
so when I try to run on ps command, I receive an error:
New-AzResourceGroup -Name az1rg -Location 'eastus'
New-AzResourceGroup : 'this.Client.SubscriptionId' cannot be null.
At line:1 char:1
If you don't set an Azure subscription, you won't be allowed to create any Azure resources without the subscription.
You need use Get-AzSubscription to list all the available subscriptions.
Then set the subscription by using Select-AzSubscription {subscription id}.
Now you could create Azure resources.
I notice that your account seems to be a guest user right?
If so, you should assign the guest user as an administrator of a subscription at first. Then the guest user can see the subscription in Powershell.
Add your System Managed Identity as Contributor role in Subscription level.
Add Contributor role on subscription level.
Correct me if I am wrong. Thank You.
The following works
Use Get-AzSubscription to list all the available subscriptions.
Set the subscription by using Select-AzSubscription {subscription id}.
This error also occurs if you are using a Managed Identity to authenticate, but the Automation Account (or Functional App) does not have a Role assigned. Assigning a Role (presumably) "homes" this identity in Subscription and populates this property automatically during authentication.
Issue reported in 2019:
https://github.com/Azure/Azure-Functions/issues/1285

How to create Azure Role Assignment scoped to a certain resource type

I'm trying to create an Azure Role Assignment which assigns the User Access Administrator role to a service principal but only for Azure Data Factory resources.
I see plenty of documentation on setting scopes by subscription, resource group, or even resource, but can't figure out how to set it for all resources of a certain type.
I've tried this PowerShell command which runs successfully but doesn't have the intended effect. The service principal still can't perform the actions of that role on ADF resources.
New-AzRoleAssignment -ObjectId ddddddd-dddd-dddd-dddd-dddddddddddd -RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9 -Scope "/providers/Microsoft.DataFactory"
I've also tried experimenting with wildcards in the scope, but this seems unsupported: /subscriptions/dddddddd-dddd-dddd-dddd-dddddddddddd/resourceGroups/*/providers/Microsoft.DataFactory/dataFactories/*
Here's the documentation I've already read:
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-definitions#assignablescopes
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-template
The Role Assignment is used to assign the user a predefined or custom role "role definition".
The role definition is the one that defines the scope of the role. The scope of the role needs to be subscription(s), resource group(s) and resource(s). You can't define a type of resource. Its more like one or multiple locations.
Structure of RBAC Scope:
https://learn.microsoft.com/en-us/azure/role-based-access-control/overview#scope
How to create a Custom Role:
https://learn.microsoft.com/en-us/azure/role-based-access-control/custom-roles
In your case, if you want to grant a user to be able to handle IAM on all DataFactory you will need to manually define each datafactory scope. Then use the actions in the Microsoft.Authorization provider: https://learn.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftauthorization
When defining the Scope for the assignment you can either define it with the -Scope <String> parameter or a combination of the following parameters.
-ResourceGroupName <String>
-ResourceName <String>
-ResourceType <String>
The resource type "-ResourceType ". For e.g. Microsoft.Network/virtualNetworks. Should only be used in conjunction with ResourceGroupName, ResourceName and (optionally)ParentResource parameters to construct a hierarchical scope in the form of a relative URI that identifies a resource.
For more details see: https://learn.microsoft.com/en-us/powershell/module/az.resources/new-azroleassignment?view=azps-3.3.0
the existing answer is pretty much on point, however there are a few things you can do to make it work:
the most obvious limit all data factories to a single resource group (or a couple of them) and grant SP owner permissions to those resource groups (or create a custom RBAC role).
use a simple script to assign those permissions dynamically
If you cant put all of the data factories in the same resource group\set of resource groups. Script would look like this ("pseudo" code, not tested, but will give you the idea):
Get-AzSbuscription | Foreach-Object {
$_ | Select-AzSubscription
Get-AzDataFactory | Foreach-Object {
New-AzRoleAssignment -Scope $_.ResourceId`
-ObjectId ddddddd-dddd-dddd-dddd-dddddddddddd `
-RoleDefinitionId 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9
}
}
and run it on a schedule

Least Priviledge Role to start/stop vm in Azure

is there any standard role that give privileges to start/stop Virtual Machines in Azure resource group without give also creation privileges or privileges to modify existing resources? I didn't found one in the documentation, the only solution is create custom roles?
yes, the only solution is to create custom role, sample powershell:
$subs = Get-AzureRmSubscription
# Resource start\stop role
$role = Get-AzureRmRoleDefinition "Virtual Machine Contributor"
$role.Id = $null
$role.Name = "Resource Start/Stop (Scheduled)"
$role.Description = "Can read\start\stop VMs"
$role.Actions.Clear()
$role.Actions.Add("Microsoft.Compute/virtualMachines/deallocate/action")
$role.Actions.Add("Microsoft.Compute/virtualMachines/read")
$role.Actions.Add("Microsoft.Compute/virtualMachines/restart/action")
$role.Actions.Add("Microsoft.Compute/virtualMachines/start/action")
$role.AssignableScopes.Clear()
$subs | ForEach-Object {
$scope = "/subscriptions/{0}" -f $_.Id
$role.AssignableScopes.Add($scope)
}
$def = New-AzureRmRoleDefinition -Role $role
you can remove restart action if you dont need to restart vms

Resources