Making an Azure service principal for website CI/CD
06 Mar 2023
This post is going to be very hard to play with if you don’t have a full-featured Azure subscription.
Create an Azure resource group
Unlike A Cloud Guru sandboxes, brand new full-featured Azure subscriptions don’t come with any resource groups.
Here’s some PowerShell by which you can create one called myfirstresourcegroup
(whose name we’ll cache into a PowerShell variable called “$my_resource_group_name
” for later convenience) located in the Central United States:
$my_resource_group_name = "myfirstresourcegroup"
New-AzResourceGroup -Name $my_resource_group_name -Location centralus
Alternatively, this should also create the same resource group and cache its name into a PowerShell variable called $my_resource_group_name
(of course, you’ll also end up with a PowerShell variable holding an object that’s called `$my_resource_group):
$my_resource_group = New-AzResourceGroup -Name "myfirstresourcegroup" -Location centralus
$my_resource_group_name = $my_resource_group.ResourceGroupName
Create an Azure AD app registration and service principal
You could ask Azure to create the Azure Active Directory Service Principal, and it’s smart enough to figure out that since you didn’t tell it a specific Azure Active Directory App Registration to link it to, it needs to create one of those too and do the linkage:
$my_service_principal = New-AzADServicePrincipal -DisplayName "My First Service Principal"
Or you could do both parts by hand for more fine-grained control:
# TODO: figure this one out
Deletion
If you need to blow the app registration and service principal out of the water and start over, here is the code to delete it if you only created one called “My First Service Principal
”:
Remove-AzADApplication `
-ObjectId ( `
Get-AzAdApplication `
-AppId ( `
( `
Get-AzAdServicePrincipal `
-DisplayName "My First Service Principal"
).AppId `
)
).Id
If you already created 2 service principals called “My First Service Principal,” you’ll get the following error:
Get-AzADApplication : Cannot process argument transformation on parameter 'ApplicationId'. Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Guid".
You can see whether that’s what you did by seeing whether this displays a table with 2 or more results (once you’ve deleted them all, it should display 0 results):
Get-AzADServicePrincipal `
-DisplayName "My First Service Principal" `
| ForEach-Object `
- Process `
{ `
Get-AzAdApplication -AppId $_.AppId; `
}
If you want to delete them all at once (obviously you wouldn’t be this casual in a production environment), you can run this code:
Get-AzADServicePrincipal `
-DisplayName "My First Service Principal" `
| ForEach-Object `
- Process `
{ `
Remove-AzAdApplication `
-ObjectId ( `
Get-AzAdApplication `
-AppId $_.AppId `
).Id; `
}
Give the service principal permissions appropriate for web development
Make sure you’ve only got one service principal with the display name of “My First Service Principal” if you’re going to use this sample code. (I’m not sure, should you have more than 1, whether this codebase would make them all website contributors or error out.)
The Azure “built-in role” of “Website Contributor” is a pretty good set of permissions for letting a CI/CD tool deploy built codebases into various Azure services that host websites, so let’s make our service principal a website contributor:
New-AzRoleAssignment `
- Description "Let my SP contribute to websites in my RG" `
- ApplicationId ( `
( `
Get-AzAdServicePrincipal `
-DisplayName "My First Service Principal"
).AppId `
) `
- Scope ( `
( `
Get-AzResourceGroup `
-ResourceGroupName $my_resource_group_name `
).ResourceId `
) `
- RoleDefinitionName "Website Contributor" `
- ObjectType "ServicePrincipal"
Deletion
If you need to delete this Web Contributor “role assignment” from your service principal, run this code (again, sample code presumes you only have one service principal called “My First Service Principal” – I’m not sure, should you have more than 1, whether this codebase revoke Website Contributor from all of them or error out):
Remove-AzRoleAssignment `
- ObjectId ( `
( `
Get-AzRoleAssignment `
-ResourceGroupName $my_resource_group_name `
-RoleDefinitionName "Website Contributor"
).ObjectId `
) `
- Scope ( `
( `
Get-AzResourceGroup `
-ResourceGroupName $my_resource_group_name `
).ResourceId `
) `
- RoleDefinitionName "Website Contributor" `
Grab the secrets for using your service principal
You’ll also need the following 4 pieces of data about your service principal, now that it exists, to let something like a CI/CD pipeline authenticate into Azure as it:
- its Client Secret
- its Client ID
- your Azure Tenant ID
- the Azure Subscription ID in which you created the service principal
TODO: Write about logging into PowerShell with an appropriate tenant/subscription
That said, you only explicitly need them, and only explicitly need them in specific formats, for outside-of-Azure CI/CD tools.
If you’re using Azure DevOps Pipelines, there are more point-and-clickey ways to specify which Service Principal’s credentials should be fed into your Pipeline’s execution.