Deployment pipeline of Azure Service Bus with Managed Identity authentication
Published: 2021-11-03 12:43:38

# Summary
Azure Managed Identity works for Azure resource authentication without secret keys. Among some authentication method options, this is the best way to secure the system as secret key management costs you a lot, for example, key storage, rotation, leakage management etc. However, managed identity authentication requires a bit more work to build infrastructure of the system because it needs high privileged permissions of Azure AD (Active Directory) and Azure Subscription, which makes it difficult to build automated deployment pipelines.

**Related sample codes**
- [azuredeploy.json](https://github.com/koheikawata/weather-app/blob/main/arm-templates/azuredeploy.json)
- [iac-pipeline-template.yml](https://github.com/koheikawata/weather-app/blob/main/pipelines/azure-devops/iac/iac-pipeline-template.yml)
- [MessageController.cs](https://github.com/koheikawata/weather-app/blob/main/src/WeatherApi/WeatherApi/Controllers/MessageController.cs) 

# TOC
- [Context](#context)
  - [Service Bus authentication options](#1-1)
  - [Problems of Managed Identity authentication](#1-2)
- [Azure role and Azure AD role](#2)
- [Deployment pipeline](#3)
   - [Assign Azure roles of Service Bus](#3-1)
- [Reference](#reference)

# Context 
## Service Bus authentication options <a name="1-1"></a>
Azure Service Bus has three options for its authentication method.
- Shared Access Signature
  - Set up a policy for each queue and topic such as `Listen`, `Send`, `Manage` and issue a shared access signature (similar to connection string). This allows you to grant least privileged permissions to different topics and queues. The problem of this method is it requires secret key management.

- Azure AD Service Principal
  - You register apps in Azure AD and generate a secret key. A client app can receive a token by submitting the registered app's client ID and secret key. This also requires secret key management.

- Azure AD Managed Identity
  - You issue a managed identity (System-assinged or User-assigned) in a client app resource, for example, Azure Virtual Machine, Azure Web App, Azure Functions, etc. Then you grant Service Bus permissions to the managed identity (Azure AD Object ID) so the client app can access Service Bus. The client app runs a code like .NET application with `Azure.Identity` package.

## Problems of Managed Identity authentication <a name="1-2"></a>
This method does not require secret key management, which is very secure, but requires Azure Subscription Owner role. This has to be a problem for an automated deployment pipeline because you do not want to grant Subscription owner role to Azure DevOps pipeline service principal. The Azure DevOps service principal has rights to deploy Azure resources through the Infrastructure as Code pipeline, but does not have a right to set up managed identity access for Service Bus. Then you need to have at least one manual step in the pipeline.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggj0g1bbid6f57r0au1w.png) 

# Azure role and Azure AD role <a name="2"></a>
In the beginning, I was confused of differnce between Azure role and Azure AD role. For Service Bus authenticaiton, you are required to have Subscription Owner role, which is Azure role, not Azure AD role. Below shows difference between Azure role and Azure AD role.

**Azure role (RBAC)**
- Target
   - Azure subscription
   - Azure resource access
- Built-in role examples
   - Owner
   - Contributor
   - Reader
   - Azure Service Bus Data Receiver
   - Azure Service Bus Data Sender
- Required for assignment
   - Owner
   - User Access Administrator
   - `Microsoft.Authorization/roleAssignments/write`
- Assignment tool
   - Azure Portal (IAM)
   - Powershell
   - Azure CLI
   - REST API

**Azure AD role**
- Target
   - Azure tenant
   - User, Group, Service Principal, Graph API
- Built-in role examples
   - Global Administrator
   - Application Developer
   - User Administrator
   - Billing Administrator
- Required for assignment
   - Global Administrator
   - Privileged Role Administrator
   - `microsoft.directory/roleAssignments/allProperties/allTasks`
- Assignment tool
   - Azure Portal
   - Powershell
   - Microsoft Graph API

# Deployment pipeline <a name="3"></a>
## Assign Azure roles of Service Bus <a name="3-1"></a>
After a IaC pipeline deployes Azure App Service and Azure Service Bus, you need to assign the necessary Azure roles to the managed identity of App Service. If the app reads and writes messages to Service Bus, both `Azure Service Bus Data Receiver` and `Azure Service Bus Data Sender` roles have to be assigned. (`Contributor` role is not enough)

With Subscription Owner or User Access Administrator role, you run the powershell command below on Azure.

```shell
$RoleReceiver = "Azure Service Bus Data Receiver"
$RoleSender = "Azure Service Bus Data Sender"
$AppServiceObjectId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$SubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
$ResourceGroup = "rg-sample-dev"
$ServiceBusNamespace = "sb-sample-dev"

az role assignment create `
--role $RoleReceiver `
--assignee $AppServiceObjectId `
--scope /subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.ServiceBus/namespaces/$ServiceBusNamespace

az role assignment create `
--role $RoleSender `
--assignee $AppServiceObjectId `
--scope /subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.ServiceBus/namespaces/$ServiceBusNamespace
``` 

# Reference
- [Azure built-in roles](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles)
- [Azure AD built-in roles](https://docs.microsoft.com/en-us/azure/active-directory/roles/permissions-reference)
- [Classic subscription administrator roles, Azure roles, and Azure AD roles](https://docs.microsoft.com/en-us/azure/role-based-access-control/rbac-and-directory-admin-roles#differences-between-azure-roles-and-azure-ad-roles)