This is a topic I have written a few blog posts about all ready, but it is becoming a frequently asked question on how to do it since most projects sooner or later will start to automate deployment from their build environment, such as Jenkins, Octupus, TFS, etc. The current documentation explains in detail the steps to do this but I’ve found that sometimes the even getting to step 1 is blocked because most AD admins says “Whoa, what? You want to create a Service Principal in the AD??”. This post tries to explain what we do, why we do it and who needs to do it.
Where we do it
This usually starts because a development project wants to automate something in their Azure subscription. The subscription belongs to the Account Admins Azure AD directory, so the place to start is to find out which directory that is.
A common question I’ve got lately is “can’t I use another directory” and the simple answer is NO, you can’t unless you want to transfer ownership of the subscription. In 99.99% of the cases you don’t want to do that. The reason for this is quite simple. You have to work with the AAD that controls authorization for your Azure subscription.
What we do
|1||Register Application||AAD Admin / AAD User
(depending on rights)
|2||Grant Application rights||Azure subscription admin|
In step 1 you are working with Azure AD which is not a resource that exists in an Azure subscriptions. It is just made available in the Azure portal for your convenience. Technically it is a stand alone product shared and used by all Microsoft Cloud products like Office 365, Intune, CRM online and Azure.
In step 2 you are working with an Azure subscription and using what you created in step 1. The AAD that an Azure subscription is connected to is determind by its Account Owner. If the account owner is email@example.com, then the subscription is connected to the disney.com AAD. So if you didn’t perform step 1 in the disney.com AAD, then step 2 isn’t going to work.
Why we do it
The creation of an Application in Azure AD creates an entry in AAD. Any application that wants to authenticate against the AAD must provite its ApplicationID to prove it is a known and legitimate application that can use AAD as its authentication source. Without it, I could write a webapp that authenticated agaist disney.com or against your directory (but since I don’t know any userid/passwords in those directories, I wouldn’t succeed).
In step 2 we actually grant the Application the right to do something, which is to work with resources in an Azure subscription.
Who needs to do it
The default setting in AAD for who can perform step 1 is that regular users in the AAD can do it themselves. If the AAD admins have flipped this switch to “No”, then only the administrators of the AAD can perform this task.
It is important to understand that the Application entry in AAD is completly harmless since it can do basically nothing in itself. You have not opened a backdoor to your company just because you created it. It is not synchronized to your on-premices Active Directory. Some organizations have flipped the switch for who can register Applications to No to prevent sprawl of many test Apps. By doing that, they also need to start working on a process for how to support the rest of the organization, because requests for creating Application entries will come and the AAD admins may become a bottleneck.
Step 2 is done by the admin in the respective Azure Subscription.
Example of creating an Azure AD Service Principal
For continous integration reasons, my imaginary project needs an Azure AD Service Principal to automate deployment. The AAD admin is Basil Fawlty who will do the registration of the application and the granting of rights inside the Azure subscription will be done by Sybil, who is the subscription admin.
Step 1 – Register Application
Basil logs in to portal.azure.com as firstname.lastname@example.org, navigates to “Azure Active Directory” and creates the Application. It is a very simple process and you only have to give it a name and a bogus sign-on URL.
Then you need to create a key which is the token to be passed out to anyone trying to use the ApplicationID.
Step 2 – Grant the Application Contributor rights to the subscription
Navigate to the subscription and Access Control (IAM) and select Add.
Select role as Contributor (or whatever meets your requirements) and then use the Select textbox to find the name of the Application you created in step 1. Save the change.
Now the Application is listed as having Contributor rights to your Azure subscription, meaning it has full rights to manage resources.
Automating login in PowerShell
To login in a PowerShell script using the Application we have created above would be like below. The Invoke-RestMethod is a conveniant way of converting your TenantName into the guid. The AppID is the guid of the ApplicationID in the Azure portal. The AppKey is the key you created in step 1 and the value to use here is the base64 string the portal shows after you have saved it – NOT the value of the key you enter.
$TenantName = "fawltytowers2"
$SubscriptionID = "...guid..."
$AppID = "...guid..."
$AppKey = "...base64 string..."
$resp = Invoke-RestMethod -Uri "https://login.windows.net/$TenantName.onmicrosoft.com/.well-known/openid-configuration"
$TenantID = $resp.authorization_endpoint.Split("/")
$password = $AppKey | ConvertTo-SecureString -asPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential($AppID,$password)
Add-AzureRmAccount -Credential $creds -ServicePrincipal -TenantId $TenantId -SubscriptionID $SubscriptionID
The equivivalent in Azure CLI would be
azure login -u $AppID -p $AppKey --service-principal --tenant $TenantID
This code can be placed in automation environments, like Jenkins and Octopus, to enable non-interactive login. You need to treat the AppKey with great caution since it is a secret like any other password.
Auditing for actions done will be recorded in the Activity Log with the credentials of the Application.
Azure documentation for creating a Service Principal
Azure documentation for logging in using a Service Principal