From Visual Studio Team Services (VSTS) it’s possible to deploy to an Azure Subscription using an Active Directory Service Principal. The Microsoft documentation refers to a blog post which describes a 3-clicks and a manual way to setup this principal. Although the information on the blog post for the 3-clicks setup is still actual, the script link provided for the manual configuration is not available anymore (not found, probably because the Git repo has been moved/renamed). For both the suggested ways (3-clicks or manual), there are some concerns from my side about the principal setup, which I think they could be improved:
- The principal which is created during the process gets the “Contributor” role granted on the whole Azure subscription, and using the manual powershell script, the default role is even “Owner” (this can be modified).
- The name of the Active Directory Application/Principal is some random guide which is difficult to be identified, see this picture:
The customer where I am currently working for, is an enterprise where multiple departments are deploying from multiple VSTS teams to the same subscription. The subscription administrators do not allow an AD Principal to be owner/contributor to the whole subscription for security/deployment errors reasons. I agree with them, a department can accidentally modify,delete,update ResourceGroups/Resources which do not belong to them using a VSTS deployment. My suggestion for the Azure Administrators was to create several principals with the role granted only to specific Resource Groups owned by the departments. In this way every VSTS Team can configure a VSTS endpoint with a principal that has enough rights to work only for their Resource Groups. That’s why I have created an improved powershell script (based on the Microsoft’s manual one) which tries to automate the Principal creation using my suggestion.
My powershell skills are limited, so please help me improve the script if you think it can be done better. Here is the GitHub repo, feel free to fork/clone it and to provide Pull Requests.
As always when dealing with security concerns, the setup needs a little more manual effort, but my powershell script tries to make it as easy as possible. The powershell script does the following:
- Create an AD Service Principal with a specified name and password (no more strange guids, the name is in your control, the name will be prefixed with “VSTS.”).
- The role (owner, contributor etc…) can be specified.
- Through a set of parameters you can provide the Resource Group names where the role for this principal will be granted on.
- Eventually create the Resource Groups if they do not exists.
- If you still want to create a Principal with a role granted at subscription level it’s still possible.
- If the AD Application, Principal, Role Assignment, Resource Groups are already present their creation will be skipped.
Using the powershell script
The powershell script uses Parameters Sets for the arguments, here are the examples with a description for the calls using the different Paramters Sets:
The granted Role is default “Contributor”, you can override it providing the parameter $spnRole (like -spnRole “owner”)
Create only an AD Application/Principal without any role grant:
.createvstsprincipal.ps1 -subscriptionName "The Subscription Name" -applicationName "TheApplicationName" -password "ThePassword"
Create an AD Application/Principal and grants the Role on the specified existing Resource Groups (if the Resource Groups do not exists no error will be thrown, they will just be ignored):
.createvstsprincipal.ps1 -subscriptionName "The Subscription Name" -applicationName "TheApplicationName" -password "ThePassword" -resourceGroupNames "ResourceGroupName1","ResourceGroupName2","etc"
Create an AD Application/Principal and the specified Resource Groups at the provided location, grants the Role to the Resource Groups:
.createvstsprincipal.ps1 -subscriptionName "The Subscription Name" -applicationName "TheApplicationName" -password "ThePassword" -resourceGroupNames "ResourceGroupName1","ResourceGroupName2","etc" -createResourceGroups -location "West Europe"
As the original Microsoft’s powershell, this creates an AD Application/Principal and grants the Role at subscription level:
.createvstsprincipal.ps1 -subscriptionName "The Subscription Name" -applicationName "TheApplicationName" -password "ThePassword" -grantRoleOnSubscriptionLevel
If a (new) department/VSTS Team needs to deploy to a (new) Resource Group, the Azure Administrator can execute the script again, the important think is to provide the same applicationName.
Configuring the Principal in VSTS
Using the powershell I have created it’s possible to have more granular control about the Azure Resources where the VSTS Principal has acces to, making the deployments more secure and the Azure Administrators happy