What Role Assignments Are Required For Bicep that assigns roles inside of Devops Pipeline?

Siegfried Heintze 1,906 Reputation points
2024-04-27T23:44:56.82+00:00

I have a bicep file (https://github.com/siegfried01/SimplerServiceBusSendReceiveDemo/blob/master/infrastructure/deploy-ServiceBusSimpleSendReceive.bicep#L365 ) that calls a bicep module (https://github.com/siegfried01/SimplerServiceBusSendReceiveDemo/blob/master/infrastructure/assignRbacRoleToFunctionApp.bicep#L16)

This works to create a service bus and function app where the function app can read the service bus queue.

However, when I try to execute this bicep file from inside a devops pipeline (https://github.com/siegfried01/SimplerServiceBusSendReceiveDemo/blob/master/azure-pipelines.yml#L116), I get this error:

ERROR: {

  "status": "Failed",

  "error": {

    "code": "DeploymentFailed",

    "target": "/subscriptions/acc26051-92a5-4ed1-a226-64a187bc27db/resourceGroups/rg_ServiceBusSimpleSendReceive/providers/Microsoft.Resources/deployments/ServiceBusSimpleSendReceive",

    "message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.",

    "details": [

      {

        "code": "InvalidTemplateDeployment",

        "message": "The template deployment failed with error: 'Authorization failed for template resource 'xxxxxxxxx' of type 'Microsoft.Authorization/roleAssignments'. The client 'xxxxxxx' with object id 'xxxx' does not have permission to perform action 'Microsoft.Authorization/roleAssignments/write' at scope '/subscriptions/xxxxxxb/resourceGroups/rg_ServiceBusSimpleSendReceive/providers/Microsoft.Authorization/roleAssignments/xxxxx'.'."

      }

    ]

  }

}
  1. I assume I need to add 'Microsoft.Authorization/roleAssignments/write' to the service connection's service principal with the scope specified in the error message. Is this true?
  2. I've tried to use the devops pipeline web GUI to modify the service connection. How do I do this? When I click on "managed service connection roles" it takes me to my subscription. Why? I (think I) want to add a "write" role to the service principal, not the subscription!
  3. When I click on manage service principal it takes me to the service principal in azure AD. I click on "Roles and administrators" and there is no way add this 'write' role.
  4. I think I would prefer to add 'Microsoft.Authorization/roleAssignments/write' with the azure CLI. How do I do that? Can I use the azure cli to create a new service principal with the scope of the resource group and the appropriatly assigned roles and use that for the service connection for my pipeline?

Thanks

Siegfried

Azure Service Bus
Azure Service Bus
An Azure service that provides cloud messaging as a service and hybrid integration.
653 questions
0 comments No comments
{count} votes

Accepted answer
  1. John Romberger 75 Reputation points
    2024-11-19T22:35:57.9333333+00:00

    Please do NOT add this service principal as an Owner of your resource group. Now anyone with access to modify DevOps Pipelines can elevate privileges to do anything they want to in the resource group, even though DevOps only needs permission to deploy resources using bicep templates (including RBAC permissions). That means they can also assign themselves or others as OWNERS of the resource group.

    The permission that fits this need best is User Access Administrator (with Conditions).

    When DevOps creates a new Connection, it creates an Application Registration in Microsoft Entra ID in Azure, under App Registrations (choose "All Applications" instead of the default "My Applications" to find it). We'll assign the User Access Administrator (with Conditions) role to this Application.

    For the best security, you should create (and remember to manage) a Managed Identity for your Function App via either the UI, Azure CLI, or a Bicep meta-deployment (just a separate deployment for your service principals that you can run before you the Administrator assign privileged permissions in the UI or via AZ CLI). In your application Bicep template, you'll assign this existing managed identity to your Function App during creation, then DevOps will be able to give it only the exact role it requires.

    Go to your resource group, IAM, and assign a role. Choose User Access Administrator, find your Azure DevOps Application (you will need to search for the FULL name found in Entra ID App Registrations), and most importantly continue to Conditions. Here, you can specifically choose only the ability of Azure DevOps to delegate the Azure Service Bus Reader role to the Managed Identity you created in the previous step. You only need to do this once, since the Managed Identity is not managed by Bicep. Reviews should be conducted regularly on Managed Identities to make sure they are still needed.

    Now in Bicep, when deploying a Service Bus application, you can specify the Managed Identity's application ID and assign Azure Service Bus Reader role scoped to the new Service Bus application within this Resource Group.

    If there are too many steps here, you can skip the Managed Identity and simplify the Condition to allow the DevOps Service Principal to assign the Azure Service Bus Reader to any user for resources in this resource group, but now anyone with access to modify DevOps could elevate their access to read from Azure Service Bus. Please balance the risk with the convenience of not maintaining a Managed Identity.


2 additional answers

Sort by: Most helpful
  1. Deepanshu katara 12,555 Reputation points
    2024-04-28T04:10:59.28+00:00

    Hi , Welcome to MS Q&A , you can perform below steps for your query

    1. Identify the Service Principal: First, you need to identify the service principal used by your Azure DevOps pipeline. You can find this information in the Azure DevOps pipeline settings.
    2. Assign Role: Once you have the service principal's details, you can use the Azure CLI to assign the required role. You can use the az role assignment create command to
         az role assignment create --role "Owner" --assignee <service_principal_id> --scope /subscriptions/xxxxxx/resourceGroups/rg_ServiceBusSimpleSendReceive
         
      
      Replace <service_principal_id> with the actual ID of your service principal.
    3. Verify: After assigning the role, you can verify if the assignment was successful by checking the role assignments for the specified scope using the az role assignment list command.

    By doing this, you're granting the necessary permission for the service principal to perform role assignments within the specified scope, resolving the error you encountered during the deployment.

    Kindly check and accept , if it helps , Thanks!


  2. Siegfried Heintze 1,906 Reputation points
    2024-05-02T13:05:04.4966667+00:00

    For future readers (which might even include me some day!):

    Since Deepanshu katara solved the problem but the actual solutions appears in the comments above and not the proposed solution, I'm designating this as the answer instead:

    $appid=(az ad sp list --display-name "sheintze-devopsdemoproject001-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" --query "[0].appId" --output tsv)
    write-output "appid=$appid"
    az role assignment create --role "Owner" --assignee $appid --scope "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_ServiceBusSimpleSendReceive"
    

    Originally, I was using ".id" instead of ".appid" and that was not working.

    sheintze-devopsdemoproject001-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is the name of the service principal created by the devops pipeline web page when my colleague helped me create a new service connection in the devops web page.

    Also, I had to run the pipeline multiple times before it started working with the above solution. Maybe there was a caching problem or something.

    It seems that this is something the devops pipeline web page should do for you with the GUI. Perhaps it is broken?

    Thank you Deepanshu katara

    Siegfried

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.