How to Automate Adding a Lab User to DevTest Labs


Acknowledgement: This post is contributed by Elizabeth Maher, Senior Software Engineer in Customer Success Team. She’s been working on a solution to help our customers to adopt Azure DevTest Labs.

Azure DevTest Labs is a good way to quickly create self-service dev-test environments.  If you are company with several teams and several DevTest Lab instances, automating the creation process can save time.  DevTest Labs ARM Templates examples show templates that allow someone to create a new lab, lab VM, custom image, formulas and add users in an automated fashion.  Today, we will focus on adding users to a DevTest Lab instance.

add a user to a DevTest Lab in an automated fashion, we need to do the same thing we do when assigning permission to any resource in Azure.  That is, we need to create a new role assignment to the DevTest Lab resource.  In this article, we will cover how to automate adding a lab user to a DevTest Lab by creating a new role assignment using Azure Resource Manager (ARM) templates, PowerShell cmdlets and the Azure CLI.

Add User via ARM Templates

Below is an example how to add a user to a DevTest Lab instance.  The full code is available in the 301-dtl-add-lab-user folder of DevTest Labs ARM Templates Examples.  Following the example, there is an explanation of the resource information and properties used in the example.

If you are assigning the role in the same template that is creating the lab, remember to add a dependency between the role assignment resource and the lab.  See Defining Dependencies in Azure Resource Manager Templates article for more information.

azuredeploy.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "principalId": {
      "type": "string",
      "metadata": {
        "description": "The objectId of the user, group, or service principal for the role."
      }
    },
    "labName": {
      "type": "string",
      "metadata": {
        "description": "The name of the new lab instance to be created."
      }
    },
    "roleAssignmentGuid": {
      "type": "string",
      "metadata": {
        "description": "Guid to use as the name for the role assignment."
      }
    }
  },
  "variables": {
    "devTestLabUserRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64')]",
    "fullDevTestLabUserRoleName": "[concat(parameters('labName'), '/Microsoft.Authorization/', parameters('roleAssignmentGuid'))]",
    "roleScope": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.DevTestLab/labs/', parameters('labName'))]"
  },
  "resources": [
    {
      "apiVersion": "2016-05-15",
      "type": "Microsoft.DevTestLab/labs",
      "name": "[parameters('labName')]",
      "location": "[resourceGroup().location]"
    },
    {
      "apiVersion": "2016-07-01",
      "type": "Microsoft.DevTestLab/labs/providers/roleAssignments",
      "name": "[variables('fullDevTestLabUserRoleName')]",
      "properties": {
        "roleDefinitionId": "[variables('devTestLabUserRoleId')]",
        "principalId": "[parameters('principalId')]",
        "scope": "[variables('roleScope')]"
      },
      "dependsOn": [
        "[resourceId('Microsoft.DevTestLab/labs', parameters('labName'))]"
      ]
    }
  ]
}

The template for assigning a role to a resource group versus a resource differ slightly.  See Role assignments template schema for further information.  All role assignment templates need to specify the resource information and role assignment specific properties, so let’s go over these in more details.

Role Assignment Resource Information

The role assignment resource needs to specify the type and name.

The first thing to note is that the type for the resource is not “Microsoft.Authorization/roleAssignments” as it would be for a resource group.  Instead, the resource type follows the pattern “{provider-namespace}/{resource-type}/providers/roleAssignments”.  In our case the resource type will be “Microsoft.DevTestLab/labs/providers/roleAssignments”.

The role assignment name itself needs to be globally unique.  We will name our assignment using the pattern “{labName}/Microsoft.Authorization/{newGuid}”.  Note that the newGuid is a parameter value for the template.  It will ensure that the role assignment name is unique.  Since there are no ARM template functions for creating new GUIDS, you need to generate a GUID yourself using any GUID generator tool.  In our template, the name for the role assignment is defined by the fullDevTestLabUserRoleName variable.  The exact line from the template is shown below.

"fullDevTestLabUserRoleName": "[concat(parameters('labName'), '/Microsoft.Authorization/', parameters('roleAssignmentGuid'))]"

Role Assignment Resource Properties

A role assignment itself defines three properties.  It needs the roleDefinitionId, principalId and scope.

Role Definition

The role definition id is the string identifier for the existing role definition.  The role id is in the form /subscriptions/{subscription-id}/providers/Microsoft.Authorization/roleDefinitions/{role-definition-id}.   The subscription id is obtained by using ‘subscription().subscriptionId’ template function.  We want the role definition for the ‘DevTest Labs User’ built-in role.  To get the GUID for the ‘DevTest Labs User’ role, we can use the Role Assignments REST API or the Get-AzureRoleDefinition cmdlet.

$dtlUserRoleDefId = (Get-AzureRmRoleDefinition -Name "DevTest Labs User").Id

In this case, the GUID is ‘76283e04-6283-4c54-8f91-bcf1374a3c64’.  So, our role id is defined in the variables section and named devTestLabUserRoleId.  The exact line is shown below.

"devTestLabUserRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64')]",

Principal Id

Principal Id is the ObjectId of the AD user, group or service principal that you want to add as a lab user to the DevTest Lab instance. In our template, we request the ObjectId as a parameter.

The ObjectId can be obtained using the Get-AzureRMADUser, Get-AzureRMAdGroup or Get-AzureRMADServicePrincipal PowerShell cmdlets.  These cmdlets return a single or list of ADObjects that have an Id property, which is the ObjectId that we need.  Below is a simple example that shows how to get the object id of a single user at a company.

$userObjectId = (Get-AzureRmADUser -UserPrincipalName ‘email@company.com').Id

You can also use the Azure AD PowerShell cmdlets that include Get-MsolUser, Get-MsolGroup, and Get-MsolServicePrincipal.

Scope

Scope specifies which resource or resource group for which the role assignment should apply.  For resources, the scope is in the form /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{provider-namespace}/{resource-type}/{resource-name}.   We use the subscription().subscriptionId’ template function to fill in the subscription-id part and the resourceGroup().name template function to fill in the resource-group-name part.  Note, using these functions means that the lab to which we are assigning a role must exist in the current subscription and the same resource group to which the ARM template deployment is made.  The last part, resource-name, is the name of the lab.  This we can get from a template parameter.

So, our role scope is defined in the variables section and named roleScope.  The exact line is shown below.

"roleScope": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.DevTestLab/labs/', parameters('labName'))]"

Deploying the Template

We have our template.  It’s time to deploy it.  Below is an example of a parameters file that might be used when deploying the template.

azuredeploy.parameters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "principalId": {
      "value": "11111111-1111-1111-1111-111111111111"
    },
    "labName": {
      "value": "MyLab"
    },
    "roleAssignmentGuid": {
      "value": "22222222-2222-2222-2222-222222222222"
    }
  }
}

Remember to deploy the template to the same resource group as the lab.  If you need help determining the resource group for a lab, use Find-AzureRMResource or Get-AzureRMResource.  If there are several labs with similar names, more than one result may be returned.

Below is an example of the script that could be used to assign a person, group or service principal Lab User access to a lab.

New-AzureRmResourceGroupDeployment -Name "MyLabResourceGroup-$(New-Guid)" -ResourceGroupName 'MyLabResourceGroup' -TemplateParameterFile .\azuredeploy.parameters.json -TemplateFile .\azuredeploy.json

It is important to note that the group deployment name and role assignment GUID need to be unique.  If you try to deploy a resource assignment with a non-unique GUID, then you will get a RoleAssignmentUpdateNotPermitted error.

If you plan to use the template several times to give several AD objects Lab User permission to your lab, consider using dynamic objects in your PowerShell command.  See below for an example that sets all the necessary template parameters on the command line.  I use the New-Guid cmdlet to specify the resource group deployment name and role assignment GUID dynamically.

New-AzureRmResourceGroupDeployment -Name "MyLabResourceGroup-$(New-Guid)" -ResourceGroupName 'MyLabResourceGroup' -TemplateFile .\azuredeploy.json -roleAssignmentGuid "$(New-Guid)" -labName "MyLab" -principalId "11111111-1111-1111-1111-111111111111"

Add User via PowerShell Cmdlets

As discussed in the introduction, we need to create a new Azure role assignment to add a user to a DevTest Lab.  In PowerShell, this can be done using the New-AzureRMRoleAssignment cmdlet. This cmdlet has many optional parameters to allow for flexibility.  The ObjectId, SigninName or ServicePrincipalName can be specified as the object being granted permissions.  To specify the resource or to which permissions are being granted can be specified by a combination of ResourceName, ResourceType, ResourceGroup or by the scope parameter.  Whatever combination of parameters used, they must provide enough information to the cmdlet uniquely identify the ADObject (user, group or service principal), scope (resource group or resource) and role definition.

Below is an example how to add a user as a DevTest Labs User to the specified lab.

New-AzureRmRoleAssignment -UserPrincipalName ‘email@company.com’ -RoleDefinitionName 'DevTest Labs User' -ResourceName 'MyLab' -ResourceGroupName 'MyLabResourceGroup' -ResourceType 'Microsoft.DevTestLab/labs'

Add User via Azure Command Line Interface

Adding a user to a DevTest Lab can be done by using the Azure CLI.  To get the Azure CLI, see the Install the Azure CLI article.  In the Azure CLI, adding a new labs user to a DevTest Lab is done by using the ‘azure role assignment create’ command.  Manage Role-Based Access Control with the Azure Command Line Interface is a good article to help you get started.

As with the PowerShell cmdlets, the object that is being granted access can be specified by the objectId, signInName, spn (ServicePrincipalName) parameters.  The lab to which the object is being granted access can be identified by the scope url or a combination of the resource-name, resource-type and resource-group parameters.

Below is an example how to add a person as a Dev Test Labs User to the specified Lab.  Note that the current subscription is specifically set in the script below.  If needed, you can use the subscription parameter to specify a specific subscription instead.

azure account login

azure account set “My Subscription Name”

azure role assignment create --roleName "DevTest Labs User" --signInName email@company.com -–resource-name "MyLab" --resource-type “Microsoft.DevTestLab/labs" --resource-group "MyLabResourceGroup"

Conclusion

We have gone over how to add a DevTest Labs User to a specific lab.  In each method, ARM templates, PowerShell and Azure CLI, we created a new Azure role assignment.  This is done by identifying object to which we want to grant permissions, the lab to which the object will be granted access and the role of ‘DevTest Labs User’.  With this information, we can now quickly automate the creation and granting of permissions to a DevTest Lab.

Comments (2)

  1. Hi,
    I have a problem with this examples. I comment an already present issue on GitHub, can you help me? This is my comment: https://github.com/Azure/azure-quickstart-templates/issues/2894#issuecomment-272451072

    Thanks!

    1. Giacomo,
      I checked the template you posted on GitHub and was able to successfully deploy to a resource group. I suspect that the issue has to do with the parameter values for the template. Could you please reply on the GitHub issue with that information? Even better would be the log from the deployment. If you feel more comfortable emailing the log info, you can get my email from my GitHub account info (https://github.com/EMaher).
      Thanks,
      Elizabeth

Skip to main content