Allow users to start/stop particular Azure VMs - azure

Our sales team will be using Azure VMs to do sales demos. I would like to be able to allow certain people to be able to start/stop their own VMs at will. I've seen being able to add people as an administrator in the management portal, but this seems to give them access to our whole subscription. I'd like to be able to manage this without having everyone create their own subscription.
Example scenario:
Person A is able to start/stop Person A's dedicated VM.
Person B is able to start/stop Person B's dedicated VM.
etc.

In order to allow a user to start and stop a virtual machine you need to create a custom role with the right permissions.
In this answer I will list the steps to follow in order to get this result using the azure command line interface. You can do the same using the Power Shell or the Azure Rest Api (find more information about the commands to be used with the Power Shell at this link and with the Azure Rest Api at this link).
Create a JSON file with the following content (let us name it newRole.json):
{
"Name": "Virtual Machine Operator",
"IsCustom": true,
"Description": "Can deallocate, start and restart virtual machines.",
"Actions": [
"Microsoft.Compute/*/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/deallocate/action"
],
"NotActions": [
],
"AssignableScopes": [
"/subscriptions/11111111-1111-1111-1111-111111111111"
]
}
A short explanation of each field of the JSON file:
Name: the name of the new role. This is the name that will be shown in the azure portal
Is Custom: specifies that it is a user defined role
Description: a short description of the role, is is shown as well in the azure portal
Actions: the list of action that can be performed by a user associated to this role. Respectively each line allows the user to:
See the list of virtual machines (not all of them, we will see later how to specify which VM will be visible to each user)
Start one of the virtual machine among those in the list
Restart one of the virtual machine among those in the list
Deallocate one of the virtual machine among those in the list
No Actions: the list of action that can't be performed by a user associated to this role. In this case the list is empty, in general it has to be a subset of the previous field.
AssignableScopes: the set of your subscriptions where the role has to be added. Each code is prefixed by the /subscription/ string. You can find the code of your subscription by accessing the subscription menu (identified by this icon)
and copy the value under SUBSCRIPTION ID column
Login to your azure account with the azure cli executing the command az login. More information about how to install the azure cli and perform the login process respectively here and here.
Create the new role executing the command az role definition create --role-definition newRole.json.
Access the portal and select the virtual machine that has to be powered on and off by a user of your choice
After you selected the machine select Access control (Iam)
From the new blade select Add
Fill in the fields as follow:
Role: Select the role you just created, in our case Virtual Machine Operator
Assign access to: Azure AD user, group, or application.
Select: the email associated to the account that needs to start/restart/stop the VM
Press save
After this operations when the user will access the portal she will see the selected VM in the list of the virtual machines. If she selects the virtual machine she will be able to start/restart/stop it.

Open your VM in portal.azure.com
navigate to Access control (IAM) → Role Assignments and click Add Role Assignment.
Select standard role Virtual Machine Contributor,
Assign access to leave by default (Azure AD user, group ...),
In Select field enter email of new limited user and select Guest.
Save.
That's all.

Ive created a custom role to allow this. I've tested and it works.
You have to start with the "Virtual Machine User Login" role then add the additional permissions. This does of course give the user log permissions as well but I assume if you are allowing them to start and stop the VM then you would also want them the ability to log in.
Via the GUI:
1. Add Custom Role
2. Select "Clone a role" and role to close is "Virtual Machine User Login"
3. Click Next
4. Select add permissions
5. Scroll down to "Microsoft.Compute.VirtualMachines" and tick
Microsoft.Compute/virtualMachines/start/action"
"Microsoft.Compute/virtualMachines/powerOff/action"
"Microsoft.Compute/virtualMachines/deallocate/action"
6. Click Next, select subscription, Next, Next then "Create".
7. List item
All permissions for the role:
Action Microsoft.Network/publicIPAddresses/read
Action Microsoft.Network/virtualNetworks/read
Action Microsoft.Network/virtualNetworks/read
Action Microsoft.Network/loadBalancers/read
Action Microsoft.Network/networkInterfaces/read
Action Microsoft.Compute/virtualMachines/*/read
Action Microsoft.Compute/virtualMachines/start/action
Action Microsoft.Compute/virtualMachines/powerOff/action
Action Microsoft.Compute/virtualMachines/deallocate/action
DataAction Microsoft.Compute/virtualMachines/login/action
Here's the JSON:
{ "properties": { "roleName": "VM_Operator_test", "description": "", "assignableScopes": [ "/subscriptions/exampesubscription/EXAMPLE_RG" ], "permissions": [ { "actions": [ "Microsoft.Network/publicIPAddresses/read", "Microsoft.Network/virtualNetworks/read", "Microsoft.Network/loadBalancers/read", "Microsoft.Network/networkInterfaces/read", "Microsoft.Compute/virtualMachines/*/read", "Microsoft.Compute/virtualMachines/start/action", "Microsoft.Compute/virtualMachines/powerOff/action", "Microsoft.Compute/virtualMachines/deallocate/action" ], "notActions": [], "dataActions": [ "Microsoft.Compute/virtualMachines/login/action" ], "notDataActions": [] } ] }}

Currently this is not possible. Though it is possible via some programming. What you see on Azure Portal can be achieved through Azure Service Management API. What you could do is write an application which consumes this API and there you could define all the rules.
If you think your sales folks will not mess around, another thing you could do is create some custom PowerShell scripts by making use of Azure PowerShell Cmdlets and they can just execute those scripts to start/stop the VMs.

My recommendation would be to build your own façade that leverages the Azure Management API to perform these tasks for you. This allows you to put in place your own controls around access/authorization as well as rig it to span multiple subscriptions (should this ever prove necessary). This façade could potentially be hosted in a free tier Azure web site.

Through azure-cli
create custom-role file "VirtualMachineStartStop.json"
{
"Name": "Virtual Machine Start Stop Access",
"IsCustom": true,
"Description": "Start/Restart/Deallocate virtual machines",
"Actions": [
"Microsoft.Storage/*/read",
"Microsoft.Network/*/read",
"Microsoft.Compute/*/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/deallocate/action"
],
"NotActions": [
],
"AssignableScopes": [
"/subscriptions/<azure_subscription_id_here>"
]
}
Create role
az role definition create --role-definition "./VirtualMachineStartStop.json"
Confirm the role creation
az role definition list --custom-role-only true

Related

ADLS Gen2 --> ACL on a folder level

I have a question regarding permissions for ADLS Gen2
short description:
I have a Gen2 storage account and created a container.
Folder Structure looks something like this
StorageAccount1
--->Container1
--->Folder1
--->Files 1....n
Also i have a service principal from a customer..
Now i have to provide the customer write only permission to only Folder1 (should not be able to delete files inside Folder1)
I have assigned the service principle below permissions in the Access control list
Container1 --> Execute
Folder1 --> Write , Execute
with this the customer can now put data into this Folder1.. but how do i prevent him from deleting any files inside it? ( i dont wanna use SAS )
Or is there any other way other than ACL?
Please help :)
ACL for ADLSgen2
Please check if below can be worked.
ACLs are the way to control access to be applied on the file and
folder level unlike others which are for container level.
Best practice is to always restrict access using (Azure RBAC)
on the Storage Account/Container level has several Azure built-in
roles that you can assign to users, groups, service principals, and
managed identities and then combine with ACLs with more restrictive
control on the file and folder level.
Ex: Storage Blob Data Contributor has read/write/delete permission .Assign an Azure role
If the built-in roles don't meet the specific needs of your
organization, you can create your own Azure custom roles.
Reference
To assign roles, you must be assigned a role that has role assignments write permission, such as Owner or User Access Administrator at the scope you are trying to assign the role.
To create a custom role with customized permissions.
Create a new file C:\CustomRoles\customrole1.json like example below. The ID should be set to null on initial role creation as a
new ID is generated automatically.
{
"Name": "Restrict user from delete operation on Storage",
"ID": null,
"IsCustom": true,
"Description": "This role will restrict the user from delete operation on the storage account. However, customer will be able to see the storage account, container, blob.",
"Actions": [
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action"
],
"NotActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/delete"
],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/move/action",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action"
],
"NotDataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete",
],
"AssignableScopes": [
"/subscriptions/dxxxx7-xxxx"
]
}
Using the above role definition, by running the below powershell script to create a custom role:
New-AzRoleDefinition -InputFile "C:\CustomRoles\customrole1.json"
see below References: for details.
How to restrict the user from upload/download or delete blob in
storage account - Microsoft Tech Community
Azure built-in roles - Azure RBAC | Microsoft Docs
Also try to enable soft delete to restore delete actions if the role has delete permissions .
Though mentioned to not use .Just in case .Shared access signature (SAS) can be used to restrict access to blob container or an individual blob. Folder in blob storage is virtual and not a real folder. You may refer to the suggestion mentioned in this article
References
permissions-are-required-to-recursively-delete-a-directory-and-its-contents
Cannot delete blobs from ADLS gen2 when connected via Private Endpoint - Microsoft Q&A
Authorize with Azure Active Directory (REST API) - Azure Storage | Microsoft Docs

How to create custom RBAC/ABAC role in Azure?

The requirement is to create access package with few roles so that the users can perform below activities:
Read & write access to data stored in a given blob container ('abc' blob container).
Role to access azure data factory to build pipeline, process & load the data to a staging area (to Blob container or SQL server).
DDL & DML and execute permission role to access the data/database in SQL server environment.
I was referring Azure RBAC and built-in-roles but unable to get clear idea considering the above points.
My question is, is there any build in roles there OR do I need to create the custom role? And, how to create custom role (for above requirements) considering baseline security?
Is there any ways, can I get additional actions by referring which I can write custom JSON scripts?
My question is, Is the RBAC roles possible for SQL Server in a VM? If yes, how?
Additionally, if I have both PaaS instance of SQL Server and VM instance of SQL Server (that is, SQL Server in VM) - how the RBAC roles will be managed for both?
According to your requirements, please go through below workarounds if they are helpful:
Read & write access to data stored in a given blob container (‘abc'
blob container).
You can make use of built-in role like Storage Blob Data Contributor which allows operations like read, write and delete Azure Storage containers and blobs. If you want to know more in detail, go through this reference.
Role to access azure data factory to build pipeline, process & load
the data to a staging area (to Blob container or SQL server).
You can make use of built-in role like Data Factory Contributor which allows operations like create and manage data factories, as well as child resources within them. Those child resources include pipelines, datasets, linked services… With this role, you can build pipeline, process and load the data. If you want to know more in detail, go through this reference.
DDL & DML and execute permission role to access the data/database in
SQL server environment.
You can make use of built-in role like SQL Server Contributor which allows operations like manage SQL Servers and Databases. If you want to know more in detail, go through this reference.
If you want to create a custom role for all these, make sure you have Owner or User Access Administrator role on the subscription. You can create a custom role in 3 ways:
Clone a role – You can make use of existing roles and modify the permissions by adding and deleting them according to your need.
Start from scratch – In this, you must add all permissions you need manually by picking them from their providers and excluding the permissions you don’t need.
Start from JSON – Here, you can just upload a JSON file where you can create separately by including all needed permissions in Actions variable whereas excluded permissions in notActions variable. If the permissions are related to data, then add them to DataActions and notDataActions based on your need. In Assignable scope, you can include the scope where the role should be available i.e., subscription or resource group as per need.
Considering baseline security, it is always suggested to give read permissions only. But as you need write permission for blob container and building pipeline, you can just add only those(read/write) in Actions section and remaining all(delete) in NotActions section.
If you want to add additional actions, simply include those permissions in Actions section in JSON file and make sure to give read permissions to resource groups.
A sample custom role JSON file for your reference:
{
"assignableScopes": [
"/"
],
"description": "Combining all 3 requirements",
"id": "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/***************************",
"name": "**********************",
"permissions": [
{
"actions": [
"Microsoft.Authorization/*/read",
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.ResourceHealth/availabilityStatuses/read",
"Microsoft.Resources/deployments/*",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/write",
"Microsoft.DataFactory/dataFactories/*",
"Microsoft.DataFactory/factories/*",
"Microsoft.Sql/locations/*/read",
"Microsoft.Sql/servers/*",
],
"notActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/delete",
"Microsoft.Sql/servers/azureADOnlyAuthentications/delete",
"Microsoft.Sql/servers/azureADOnlyAuthentications/write"
],
"dataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/move/action",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action"
],
"notDataActions": []
}
],
"roleName": "Custom Role Contributor",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions"
}
Reference:
Azure custom roles - Azure RBAC | Microsoft Docs

Deny the creation of a new management group at root level

I am trying to deny the creation of any additional management group at root level. I enabled the capability of management groups which created the "Tenant Root Group".
I created some more MGs under that one for my governance purposes but I do not want users to be able to create their own. Even without giving them any specific access, it looks that they can (even though it sounds weird to me). I double-checked in IAM panel, nothing specific is there.
Whats displayed in the Azure Portal is like this:
Root Tenant Group
|--- ManagementGroup1
|--- ManagementGroup2
|--- etc.
"Root Tenant Group" is the one that have been automatically created and that I am trying to lock now that I created my structure.
I wanted to go with an Azure Policy, but whenever I apply it to that Tenant Root Group, it does not prevent the creation of another management group. Actually it looks like in the ARM structure, they are not considered as children at all but as independent items. When I run the command az account management-group show --name MyTenantRootGroup it says "children" is null.
Still, my policy was the following:
"if": {
"source":"action",
"equals":"Microsoft.Management/managementGroups/write"
},
"then": {
"effect": "deny"
}
Is there any other way to do so ?
Policy is unable to evaluate policies at a Management group level because of outside limitations. I would recommend submitting your idea to our UserVoice for proper feedback and consideration.

ARM Template: Looking up a user object Id

I'm trying to programatically insert the object Id of a certain user account into an ARM template, like this:
"objectId": "[reference(resourceId('Microsoft.AAD/domainServices/user/read','domain','User.Name'),'2019-01-01').Id]",
I've tried many different resource providers in an attempt to get this to work. For example:
"objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/read','user#domain.onmicrosoft.com'),'2019-01-01').Id]",
and:
"objectId": "[reference(resourceId('Microsoft.Portal/usersettings/read','user#domain.onmicrosoft.com'),'2018-10-01').Id]"
I looked up the API call used to get a list of users, to see if that would hint at the correct provider to use (it didn't):
GET https://graph.windows.net/{TenantId}/users?api-version=1.6 HTTP/1.1
I've been looking through this list of provider operations but have found two problems with this:
1 I can't see an operation which looks relevant to what I want to do.
2 It doesn't provide information on what parameters are required.
So I guess I have two questions really:
How do I dynamically look up the ObjectId of a user in an ARM template?
How do I find out in future which lookup functions are available and which parameters are required?
You could not insert the user object Id in the ARM template.
The user account is managed by your Azure AD tenant, it is not the azure resource, the ARM template is for the azure resources in your subscription.
Reference:https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview
Azure Resource Manager is the deployment and management service for Azure. It provides a consistent management layer that enables you to create, update, and delete resources in your Azure subscription.
You can try from below code if you have VM in same template and enabled managed identity
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#remarks-1
{
"type": "Microsoft.KeyVault/vaults",
"properties": {
"tenantId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.tenantId]",
"accessPolicies": [
{
"tenantId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.tenantId]",
"objectId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vmName')), '2017-03-30', 'Full').identity.principalId]",
"permissions": {
"keys": [
"all"
],
"secrets": [
"all"
]
}
}
]
I find the best way to achieve this is to expose the ID as a parameter, then when you call the ARM template deployment, simply pass the parameter into the template.
How do you get the ID into the template parameter? Well, I run my ARM deployments via Azure DevOps CI/CD and I use the pipeline task AzureAppConfiguration.azure-app-configuration-task.custom-build-release-task.AzureAppConfiguration#1 to extract the ID from my own custom configuration setup.
How do you get the ID into the Azure App Configuration service? Well, when I seed an environment for the first time there will be some initial setup, e.g. users and groups. I just then run some scripts to extract this kind of "metadata" into my Azure App Configuration service.
e.g.
APP_ID=$(az ad sp list --all --query "[?displayName=='name-of-spn'].appId" --output tsv)
az appconfig kv set --name name-of-app-config-store --key name-of-spn-app-id --value ${APP_ID}
I think I have solution.
I am tying to refer to a Client ID in a Managed User Identity generated by an ARM template.
I have declared the name of the Managed Identity as a Parameter to use as an administrator for an SQL server:
[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('managed-identity')), '2018-11-30', 'full').properties.clientId]
Once you switch our the parameter you should be good to go.

Why is Azure Storage API permission not listed in azure portal?

Trying to build an app that accesses the azure storage API using AAD credentials, I noted that some API permissions are not listed within the azure portal and the only way to set them is through editing the app registration manifest directly. See my answer here for more details.
My question is simple:
Did I miss the permission for user_impersonation on Azure Storage in the portal or is it truly not listed?
If so, where can we find a complete list of all available permissions with its GUIDs so configuring the manifest manually is easier?
For instance I found the correct GUID for user_impersonation on Azure Storage somewhere on a internet forum and added it to my manifest as shown below.
"requiredResourceAccess": [
{
"resourceAppId": "e406a681-f3d4-42a8-90b6-c2b029497af1",
"resourceAccess": [
{
"id": "03e0da56-190b-40ad-a80c-ea378c433f7f",
"type": "Scope"
}
]
}
]
The result hover can be seen in the portal after modification of the manifest:
As pointed out in the comments, the entry should be visible unter "APIs my organization uses".
However, the search there is not returning anything, which seems to be a temporary bug.
You have to manually scroll through the list and hit "load more". From there you'll find Azure Storage as an API permission.

Resources