Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Provisioning Azure AD Service Principals that can deploy built webapps onto your Azure App Service resources

16 Mar 2023 🔖 beginner azure web development
💬 EN

Table of Contents

In this series, we’ve written the world’s tiniest webserver, added unit tests to its codebase, told Azure DevOps (“ADO”) Pipelines to auto-build a runnable web server for us each time we update our Git-tracked source code, and rented 2 webserver hosts from Microsoft Azure’s public cloud (one “nonproduction” and one “production”).

Every time ADO builds our source code into a runnable web server, we’ll want it to deploy the “built” codebase onto the hosts we rented. Our ADO automation will need to prove it’s not an evil hacker trying to take over our web hosts. Therefore, we need to:

  1. Create an Azure Active Directory (“AAD”) identity ADO can use to prove that it is who it says it is.
  2. Create an Azure RBAC role assignment authorizing the new AAD service principal to deploy code onto our web hosts.
    • (We’ll worry about telling ADO how to use the new AAD service principal in a subsequent article.)

Prerequisites

  1. Have an account in Azure.
  2. Log your computer’s command line into that Azure account.
  3. Determine the unique name of the Azure resource group that you’d like to create webhost resources within, and make sure it exists.
    • For this exercise, I created a brand new one named “my-hello-web-rg” inside my Azure account.

Note: In an enterprise context, your nonproduction and production webhost resources might end up in two separate Azure resource groups. In that case, you’d likely need to create 2 Azure RBAC role assignments for your AAD Service Principal (one for each resource group).

Luckily, in an enterprise setting, there’s probably another team worrying about this for you who will be provisioning Azure resource groups resources, Azure App Service Service Plan (“AASSP”) resources, AASWA resources, AAD Application Registrations, AAD Service Principals, and Azure RBAC Role Assignments for you.

For the purpose of tutorial simplicity, I am using just 1 resource group, so we’ll only create 1 Azure RBAC Role Assignment.


Provision an Azure AD application registration

In my scripts below, be sure to substitute:

  1. my-first-app-reg” if that’s not actually the name of the AAD application registration you’d like to create.

With Azure PowerShell

If ( `
    Get-AzAdApplication `
        -DisplayName "my-first-app-reg" `
) {} `
Else { `
    New-AzAdApplication `
        -DisplayName "my-first-app-reg"; `
}

With the Azure CLI

In a Windows PowerShell command prompt

If ( `
    az ad app list `
        --display-name "my-first-app-reg" `
        --query "[0]" `
) {} `
Else { `
    az ad app create `
        --display-name "my-first-app-reg"; `
}

In a Linux-style command prompt

if [ \
    $( \
        az ad app list \
            --display-name "my-first-app-reg" \
            --query "[0].id" \
    ) \
]; \
then 
    :; \
else
    az ad app create \
      --display-name "my-first-app-reg"; \
fi;

Provision an Azure AD service principal

In my scripts below, be sure to substitute:

  1. my-first-app-reg” if that’s not actually the name of the AAD application registration you just created.

With Azure PowerShell

If ( `
    Get-AzAdServicePrincipal `
        -ApplicationId ( ( `
            Get-AzAdApplication `
                -Filter "DisplayName eq 'my-first-app-reg'" `
                -First 1 `
        ).AppId ) `
) {} `
Else { `
    New-AzAdServicePrincipal `
        -ApplicationId ( ( `
            Get-AzAdApplication `
                -Filter "DisplayName eq 'my-first-app-reg'" `
                -First 1 `
        ).AppId ) `
}

With the Azure CLI

In a Windows PowerShell command prompt

If ( `
    az ad sp list `
        --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName}[0]" `
) {} `
Else { `
    az ad sp create `
        --id $( `
            az ad app list `
                --display-name "my-first-app-reg" `
                --query "[0].id" `
        ); `
}

In a Linux-style command prompt

if [ \
    $( \
        az ad sp list \
            --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName,id:id}[0].appDisplayName" \
    ) \
]; \
then 
    :; \
else
    az ad sp create \
      --id $( \
        az ad app list \
            --display-name "my-first-app-reg" \
            --query "[0].id" \
      ); \
fi;

Provision an Azure RBAC role assignment

Services logged into AAD using the “application registration” + “service principal” pair you just created can’t actually do anything useful in Azure unless you give that AAD pairing adequate Azure permissions.

A Microsoft-maintained built-in RBAC role called “Website Contributor” is a great one for CI/CD pipelines that simply need to deploy “built” web server runtimes onto Azure App Services web-hosting resources.

We’ll set up a “role assignment” to link our new AAD resource to the “website contributor” set of Azure permissions.

In my scripts below, be sure to substitute:

  1. my-first-app-reg” if that’s not actually the name of the AAD application registration you’d like to create.
  2. my-hello-web-rg” if that’s not actually the name of the resource group you created.

With Azure PowerShell

If ( `
    Get-AzRoleAssignment `
        -ObjectId ( `
            Get-AzAdServicePrincipal `
                -ApplicationId ( `
                    Get-AzAdApplication `
                        -Filter "DisplayName eq 'my-first-app-reg'" `
                        -First 1 `
                    ).AppId `
        ).Id `
        -Scope ( `
            Get-AzResourceGroup `
                -Name "my-hello-web-rg" `
        ).ResourceId `
        -RoleDefinitionName "Website Contributor" `
) {} `
Else { `
    New-AzRoleAssignment `
        -Description "let-service-principal-manage-websites-in-resource-group" `
        -ApplicationId ( `
            Get-AzAdApplication `
                -Filter "DisplayName eq 'my-first-app-reg'" `
                -First 1 `
        ).AppId `
        -Scope ( `
            Get-AzResourceGroup `
                -Name "my-hello-web-rg" `
        ).ResourceId `
        -RoleDefinitionName "Website Contributor" `
        -ObjectType "ServicePrincipal" `
}

With the Azure CLI

In a Windows PowerShell command prompt

If ( `
    az role assignment list `
        --assignee $( `
            az ad sp list `
                --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName,id:id}[0].id" `
        ) `
        --scope $( `
            az group show `
                --name "my-hello-web-rg" `
                --query "id" `
        ) `
        --role "Website Contributor" `
        --query "[0]" `
) {} `
Else { `
    az role assignment create `
        --description "let-service-principal-manage-websites-in-resource-group" `
        --assignee-object-id $( `
            az ad sp list `
                --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName,id:id}[0].id" `
        ) `
        --scope $( `
            az group show `
                --name "my-hello-web-rg" `
                --query "id" `
        ) `
        --role "Website Contributor" `
        --assignee-principal-type "ServicePrincipal"; `
}

In a Linux-style command prompt

if [ \
    $( \
        az role assignment list \
            --assignee $( \
                az ad sp list \
                    --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName,id:id}[0].id" \
                | xargs \
            ) \
            --resource-group "my-hello-web-rg" \
            --role "Website Contributor" \
            --query "[0].id" \
    ) \
]; \
then 
    :; \
else
    az role assignment create \
        --description "let-service-principal-manage-websites-in-resource-group" \
        --assignee-object-id $( \
            az ad sp list \
                --query "[?appDisplayName=='my-first-app-reg'].{appDisplayName:appDisplayName,id:id}[0].id" \
            | xargs \
        ) \
        --resource-group "my-hello-web-rg" \
        --role "Website Contributor" \
        --assignee-principal-type "ServicePrincipal"; \
fi;

Posts in this series

--- ---