Skip to content

2. Deployment

Srinivas Varukala edited this page Jan 26, 2023 · 44 revisions

Pre-requisites

Deployment machine

Permissions

  • Azure AD admin role to create the Service Account, assign roles and register a new application
  • Azure account with Privileged Role Administrator and Application Administrator roles and with Contributor role assigned at the Azure Subscription level.
  • Permissions to create a new SharePoint site

Note: in this deployment, we assume that the same user has the appropriate permissions to deploy the resources on Azure, Power Platform and Azure AD. This is however not mandatory and the deployment can be split across these different roles and responsibilities within the organization.

Licenses/Subscriptions

  • Azure Subscription associated with M365 tenant
  • M365 Subscription (to create the SharePoint site). This is the same M365 subscription where the Teams Call Queues are hosted.
  • Power App license to deploy the application and Power Automate flows
  • Power App premium license (per app) is required. See Configuraiton page for details.

Step 1: Install the prerequisites

Install PowerShell 7.x

Use the steps below to install PowerShell 7.x on the machine used for the deployment of the app:

  1. Go to https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.2#msi
  2. Select the correct platform (x64 or x86)
  3. Once the file has been downloaded install the MSI

Install Azure Az PowerShell module

Use the steps below to install the Azure Az PowerShell module:

  1. In your start menu search for PowerShell 7, once found click on it to open PowerShell 7
  2. Run the following cmdlet to install the latest version of the Azure Az PowerShell module:
Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force

This will install the Azure Az PowerShell module only for the user which is currently logged in.

Install Microsoft Graph PowerShell module

Use the steps below to install the Microsoft Graph PowerShell module:

  1. If you closed the previous PowerShell window, search in the start menu for PowerShell 7, once found click on it to open PowerShell 7
  2. Run the following cmdlet to install the latest version of the Microsoft Graph PowerShell module:
Install-Module Microsoft.Graph -Scope CurrentUser -Repository PSGallery -Force

This will install the Microsoft Graph PowerShell module only for the user which is currently logged in.

Install Microsoft PnP PowerShell module

Use the steps below to install the Microsoft Graph PowerShell module:

  1. If you closed the previous PowerShell window, search in the start menu for PowerShell 7, once found click on it to open PowerShell 7
  2. Run the following cmdlet to install the latest version of the PnP PowerShell module:
Install-Module -Name "PnP.PowerShell" -Scope CurrentUser -Repository PSGallery -Force

This will install the PnP PowerShell module only for the user which is currently logged in.

Step 2: Create a Service Account in Azure AD

Purpose of service account

  • This account will be used to run the Microsoft Teams PowerShell scripts within the Azure Function. Since Call Queue API is not available in Microsoft Graph, this is the recommended way to communicate with Call Queue programmatically.

Follow below steps to create a service account:

  1. Log into Azure Portal using an account that have the permissions to create and manage Azure AD Users. User Administrator role or above will suffice for this account.

  2. Go to the Azure AD portal to manage users

  3. Add a new user (e.g. "Call Queue Service Account") and save the password

  4. Under assigned roles assign the following roles:

    • Teams Communications Administration

    Note: do not enable multi-factor authentication (MFA) for this account.

  5. You'll need to reset this password the first time you use this account - Please connect to https://portal.azure.com with the user credentials and provide a new complex password - Store this password in a secured location. Take into consideration your organization's password expiration policy. You can either disable password expiration for this service account, or ensure your operational support model includes a password rotation plan.

Step 3: Deploy the Azure resources

The deployment script must be run by an account with below roles.

User Roles:

  • Application Administrator
  • Privileged Role Administrator

Azure Suscription Role:

  • Contributor

During the creation of the resources the following permissions will be automatically configured:

  • Account which is used to execute this script: get/list/create/update secrets
  • Azure Function managed identity: get/list secrets
  • Azure Function managed identity will receive the following Graph Permissions
    • Sites.Selected
    • User.Read.All

To execute this deployment step, you need to download the content of this repository on your local environment and run the PowerShell script under .\Deployment\deploy.ps1

  1. Download the content of this repository
  2. Execute the script deploy.ps1 as follow:
.\deploy.ps1 -displayName <Name of Azure AD registered app> -rgName <Name of the resource group> -resourcePrefix <prefix for Azure resources -location <Azure region> -serviceAccountUPN <UPN of the service account created in step 1> -serviceAccountSecret <Password of the service account created in step 1>` (optional) -subscriptionID <Azure subscription id>

Example

.\deploy.ps1 -displayName "cqsaadapp" -rgName "msteams-cqsapp" -resourcePrefix "CQS" -location "East US" -serviceAccountUPN cqsmgr@tenant.onmicrosoft.com -serviceAccountSecret abc123 -subscriptionID eb1fbaa5-1234-4321-1234-747acead31bb

The deployment can take several minutes, including the warm-up time of the Azure Functions - At the end of the deployment, check the outputs that will be required to configure the deployment of the Power App and Azure AD Conditional Access

A successful deployment should look like that (by default, the script runs 3 times)

Deployment script completed.

Here is the information you ll need to deploy and configure the Power Application
FunctionApp       : 'https://cqs-function-6cdgs.azurewebsites.net'
Tenant        : 'contoso.onmicrosoft.com'
TenantID      : 'be195bd3-xxxx-xxxx-xxxx-9d7d95a5dcf7
AzFunctionAADApplicationID      : 'bad28fb5-xxxx-xxxx-xxxx-665886c2cbad'
AzFunctionAADAppIDURI     : 'api://azfunc-5ab68824-5cfc-4402-8b8e-aa6cd14cf6ed'
AzFunctionManagedID   : 'ba47870f-28f8-4f03-b8fb-ca5aceb4ed54'
CustomConnectorAADApplicationID   : '6ec9bc51-xxxx-xxxx-xxxx-a0d64bfb81e0'
KeyVaultName : 'cqs-keyvault-6cdgs'

Step 4: Modify the Azure Function App and Test a function

The steps listed below describe how to migrate the Azure Function App from running as a package to a solution which does not pull it's package from this repository.

Open Azure Portal.

  1. Navigate to 'Resource Groups'. Select the Resource Group you created in Step 3
  2. Select the Azure function app that was created by the deployment script
  3. From the left menu select Advanced Tools in the Development Tools section
  4. In the main pane select go
  5. From the top menu select **Debug Console **and select PowerShell
  6. Wait till everything is loaded
  7. In the "explorer" view select site
  8. Beside the wwwroot folder, select the Download icon to download a zip with all the content
  9. Wait for the download the be completed
  10. Go back to the Azure Function page and select Configuration in the Settings section
  11. Search for the entry WEBSITE_RUN_FROM_PACKAGE
  12. Delete the entry completely.
  13. Click Save to save the Azure Function updated configuration.
  14. After a few seconds/minutes go to Functions in the Functions section and you will see everything has been removed
  15. Go back to the Debug Console window
  16. Inside the wwwroot put the content from the previously downloaded zip into the directory.
    • Extract the previously downloaded ZIP file to a separate folder on your deployment machine.
    • Drag and drop the files from the extracted folder to the Debug Console to the root of the wwwroot directory.
  17. Go back to the Function App page and validate the functions are visible again. Click Refresh if needed.

Change Authentication Settings

  • Select Authentication in the Settings section. Click Edit located beside Application settings.
  • Select HTTP 302 Found redirect option for Unauthenticated requests. Click Save.

To test your Azure Function Setup

  • While your Azure Function app is opened in Azure Portal, click on Functions.
  • Then click on ListCallQueue. Click on Get Function Url. Copy the URL.
  • Paste in a new tab in the browser. It will prompt you to login. Consent the permissions it requests.
  • You must see the results that shows all your Call Queues and its agents.
  • Please see FAQ page heading Troubleshoot Azure Function if the function fails to work

Step 5: Create SPO Site, Permissions and the requred lists

To run this script any licensed user will work unless your organization limits who can create an M365 Group see this.

If PnP PowerShell is not consented in your Tenant, you will require to use an account with at least Application Administrator Azure role to consent the permissions.

During the creation of the resources the following permissions will be automatically configured:

  • The account running the script will be added as the owner of the SPO site
  • The managed identity corresponding to the Azure Function will be given "Write" granular permission on the SPO site
  • The required lists and libraries will be created in the SPO site. You can review the site template file here: .\Pkgs\cqs-manager-site-lists.xml.

To execute this deployment step:

  • Open a new PowerShell v7 terminal window (do not use the same window that was used for Step 3)
  • You need to download the content of this repository on your local environment and run the PowerShell script under .\Deployment\deploy-spo.ps1
.\deploy-spo.ps1 -SPOSiteTitle <Title for your site> -AzFunctionMID <Paste the AzFunctionManagedID that was part of the output in Step 3> -SPOHostUrl <Provide your tenant host url e.x "moderncomms996974.sharepoint.com">

Example

.\deploy-spo.ps1 -SPOSiteTitle "CQS Trial" -AzFunctionMID "a1381a7b-xxxx-xxxx-xxxx-554e285cb7d0" -SPOHostUrl "contoso.sharepoint.com"

Note: Please note down the output that this script generates. It's needed for the app configuration.

Once executed go to the SharePoint Online site and validate the SharePoint Lists created (shown below)

Step 6: Update the app settings for the Azure Function App

  1. Navigate to Azure Portal, open the resource group and edit the Azure Function.
  2. Click on Configuration in the left nav.
  3. Under the Application Settings tab you will find few entries. Please edit the below entries
  • ShiftsMgrCallQueueOwnersListId provide the CallQueueOwners List ID (found in the outputs from Step 5)
  • ShiftsMgrSPOSiteId: provide the SPO Site ID (found in the outputs from Step 5)
  • ShiftsMgrManifestListId: provide the ShiftsManfiest List ID (found in the outputs from Step 5)
  • ShiftsMgrChangeLogListId: provide the ShiftsChangeLog List ID (found in the outputs from Step 5)
  1. Click on Save located in the top of the page to save these updates.

Step 7: Deploy the Custom Connector

ALERT: Please do not deploy Power Platform components to the default environment. Instead use an environment created for your line of business applications or a dedicated environment for this application.

As per recommended pattern, this solution uses a custom connector as a wrapper to access Azure Functions API. Deploying the Custom Connector is being performed by importing a solution in the Power Apps environment. It is recommended to import the solution in a separate Power App environment if possible.

  1. Go to https://make.powerapps.com
  2. In the left menu select Solutions

    Note: If this is the first time you are navigating to this page, you will be prompted to create a CDS/Dataverse database. Go ahead and accept it. It will take about 15 mins for this to provision.

  3. From the top menu select Import
  4. In the new pane validate the correct environment is selected and press browse
  5. Select the ZIP file named CQSCustomConnectorSolution_x_x_x_x.zip from the Pkgs folder
  6. Press the Next button to continue
  7. Review the details of the package and press Next
  8. You will be propmpted to enter information for environment variables.
  • CustomConnectorAzFunctionHostUrl - enter your Azure function app host url (example: if your function app is https://cqsapp.azurewebsites.net, you enter cqsapp.azurewebsites.net as the value)
  • CustomConnectorAADAppSecret - enter the CustomConnectorAADApplicationSecret value from Step 3's output
  • CustomConnectorAADAppID - enter the CustomConnectorAADApplicationID value from Step 3's output
  • CustomConnectorResourceUrl - enter the AzFunctionAADAppIDURI value from Step 3's output
  1. Press Import to complete the solution import. It's normal for the import process to take couple of minutes to complete.
  2. Open the imported solution (CQS-CustomConnector-Solution). You will see 4 environment variables and 1 custom connector called CQSConnector. Use the ellipses for the CQSConnector and click Edit.
  3. Go to Test tab
  4. Ensure ListCallQueues is selected under Operations.
  5. Click + New connection. It will prompt you to login.
  6. Once logged in, you will see prompt to consent below permissions. Please go ahead and select Consent on behalf of your organization and consent the permissions.
  • Access cqsapptrial (cqsapptrial)
  • Sign you in and read your profile
  1. Ensure you are seeing the connection populated and selected in the Selected Connection dropdown. If you are not seeing it, please check the FAQ page for troubleshooting steps. Look for heading that contains New Connection is not populated
  2. Now click Test operation button. The response output must show all the Call Queues from your Teams admin center. Custom Connector Screen

Step 8: Deploy the Power App and flows

Deploying the Power App and Flows is being performed by importing a solution in the Power Apps environment. You can use the same Environment that was used to deploy the custom connector is Step 6.

To import the solution perform the following steps:

  1. Go to https://make.powerapps.com
  2. In the left menu select Solutions

    Note: If this is the first time you are navigating to this page, you will be prompted to create a CDS/Dataverse database. Go ahead and accept it. It will take about 10 - 15 mins for this to provision.

  3. From the top menu select Import
  4. In the new pane validate the correct environment is selected and press browse
  5. Select the ZIP file named CQSPowerPlatSolution_x_x_x_x.zip from the Pkgs folder
  6. Press the Next button to continue
  7. Review the details of the package and press Next
  8. Update the SharePoint CQSAdvVoiceSolution-345... connection by selecting the dropdown menu next to the connection and select the New Connection option, a new tab will be opened (don't close the previous tab)
  9. On the new tab select Connect directly (cloud-services) and press Create
  10. An authentication prompt will be shown, provide your credentials or of any account with a valid M365 license. Irrespective of the account used here, the custom connector will impersonate the currently logged in user to the PowerApp.
  11. Close the tab and go back to the original tab and press the **Refresh **button
  12. Select the connection created from the drop down list
  13. Repeat steps 8 to 12 for the remaining two Connections.
  • Office 365 Users CQSAdvVoiceSolution
  • CQSConnector CQSAdvVoiceSolution
  1. Once all 3 connections have been updated press the Next button
  2. Populate the fields with the values provided in the output of the script in Step5:
  • ManifestArchiveDocLibraryName: Set the value as ShiftsManifestArchive
  • CSVDocsLibraryName: Set the value as ShiftsCSVDocuments
  • CQS-SPO-Site: value of the SPO Site URL. e.g. https://contoso.sharepoint.com/sites/CQSDemo
  • ShiftsCSVDocuments: select the ShiftsCSVDocuments library from the dropwdown
  • ShiftsManifest: select the ShiftsManifest list from the dropdown
  • CallQueueOwners: select the CallQueueOwners list from the dropdown
  • ShiftsTimeZone: timezone of the agents (e.g. PST). See reference here: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations

  1. Once all values are provided continue with importing the solution, this might take several minutes. While importing a message will be show on the top of the page highlighting that the solution is being imported.
  2. Once imported you will see the CQS-PowerPlat-Solution entry in the list of solutions
  3. Click on the 3 dots and select Edit
  4. Click on Apps in left nav and find the Call Queue Scheduler app
  5. Click on the 3 dots and select Edit
  6. You will see a popup with a list of connectors used by the app. Use the Sign in button listed against any of the connections. Follow the prompts and Allow access. Provide your credentials.
  7. Wait for the app to load and play the app. Click Manage Call Queue to see the call queue and add/remove agents to it. Note that you can add only those users that are enterprise voice enabled.