Friday, September 14, 2018

Office 365 site self-provisioning with SharePoint Framework (SPFx), Azure Logic Apps, Queue, and Azure Function


About three years, when we first looked at the Office 365 site provisioning for the company, there were limited options. The best option at that time was using provider hosted SharePoint add-in architecture similar like posted here. Since then PnP provisioning package came out and has been gone through multiple iterations. With many Azure services available and integration with O365 now, there are more better options like the one published here. We have put together the Office 365 Modern Provisioning architecture and implemented using SharePoint Framework (SPFx), Azure Logic Apps, Queue, and Azure Function for the company. We will compare some alternative and options in the blog. We will cover SharePoint on-premises site self-provisioning with SharePoint Framework (SPFx), Azure Logic Apps, Queue, and Azure Function in another blog.

The Office 365 site self-provisioning architecture is illustrated in the below diagram. Here are the components.
  
  • User enters site provisioning information from SharePoint Framework (SPFx) form on SPO site.
  • The new list item created will trigger the Azure Logic app to send to approval.
  • If the request approved, Azure Logic App will send the request to Azure queue with request ID that is list item ID.
  • Azure queue will trigger the Azure function to provision the site collection and perform post provisioning steps.


Here is the details for each component and different alternative.

1. The first component is SharePoint online list that will store all the user site request. The reason we use this is to capture the site creation request for history and analysis. The list should have minimal the following fields. You could adjust fields based on your business requirement.
  • SPSiteTitle
  • SPSiteURL
  • SPSiteType
  • SPSiteDescriptions
  • SPSiteOwners
  • SPSiteMembers
  • SPSiteVistors
  • ApprovalStatus – Capture the approval status
  • ProvisioningStatus – This will be used to indicate if site create successfully

2. The second component is SharePoint Framework (SPFx) form. You could use Azure PowerApps, blot, SharePoint add-in as alternatives. The reason we select SPFx form because we need extensive field validation. One example is when user enters the site URL, we need to verify if the URL is already in SharePoint or already in the request list. Our current SPFx form looks like the screen below.


3. The third component is the Azure Logic App. The Logic App will be triggered when new site request SharePoint online list item created. You could use Azure flow or WebJob as alternatives. The reason we select Azure Logic App because we have not open flow for users and we would like to control all components inside same place. In this case is inside Azure resource groups.


4. The forth component is the Azure storage queue. The queue has the site provisioning request information that will trigger the Azure function. The reason we choice the queue is to decouple the services and we will extend to support both  SharePoint online and SharePoint on-premises site provisioning. We decided to only include the "RequestId" in the queue to indicate the request list item ID. This will make the design flexible since any fields we need to add to the site creation will not impact the queue. The queue looks like this below. 

{
"RequestId": "86"
}

5. The firth component is the Azure function. We use PnP PowerShell as the implementation. You can use any language as the implementation but PnP PowerShell is much simpler. The only concern is PowerShell support is experimental at current V1.x. We are hoping future PowerShell V2.x will still be supported in Azure function. Here is the snippet of the Azure function code.

#Import dll from library
Import-Module "D:\home\site\wwwroot\yourmodulefodler\modules\SharePointPnPPowerShellOnline.psd1" -Global;
Import-Module "D:\home\site\wwwroot\yourmodulefodler\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell" -Global;

#Get trigger content
$requestBody = Get-Content $triggerInput -Raw | ConvertFrom-Json

#Initial variables
$username = $env:sssp_username
$password = $env:sssp_password
$requestListSiteUrl = $env:sssp_requestsiteurl
$requestList = $env:sssp_requestlistname
$siteCollectionRootURL = $env:sssp_rooturl
$SiteDesign ="Topic"    #Right now hard coded to Topic only
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)

#Get request ID from queue
$requestID = $requestBody.RequestId

#Use request ID from the queue to retrive request information form the SPO site request list

    # Connect to request site and get request information based on request ID
    Connect-PnPOnline -url $requestListSiteUrl -Credentials $creds

    #Get request item
    $requestItem = Get-PnPListItem -List $requestList -Id $requestID
    $requestItem

    #Get all required site request information
    $requestSiteTitle$requestItem["SPSiteName"]
    $requestSiteUrl = $requestItem["SPSiteURL"]
    $requestDescription = $requestItem["SPSiteDescription"]
    $requestSiteOwners = $requestItem["SPSiteOwners"]
    $requestSiteMembers = $requestItem["SPSiteMembers"]
    $requestSiteVisitors = $requestItem["SPSiteVisitors"]
    $requestSiteType = $requestItem["SPSiteType"]

    #Create the site collection
    $siteCollectionURL = $siteCollectionRootURL + $requestSiteUrl

    $newSiteUrl = New-PnPSite -Type CommunicationSite -Title $requestSiteTitle -Url $siteCollectionURL -Description $requestDescription -SiteDesign $SiteDesign

    #Connect to the new created site collection
    Connect-PnPOnline -url $siteCollectionURL -Credentials $creds

    #Add additional site collection admin
    Add-PnPSiteCollectionAdmin -Owners additionalowner@mycompany.com

    foreach ($owner in $requestSiteOwners)
    {
        #Add-PnPUserToGroup -LoginName $ownerEmail -Identity $siteOwnersGroup
        if($owner.Email -ne $null -and $owner.Email -ne "")
        {
            Add-PnPUserToGroup -LoginName $owner.Email -Identity 3
        }
        else
        {
            Add-PnPUserToGroup -LoginName $owner.LookupValue -Identity 3
        }
    }
    # Other post provisioning steps …
    # Connect to request site and set ProvisioningStatus to "Provisioned"

There are few enhancements you could do. One example is  you can set up a app and use AppId and App Secret in the Powershell as below.

Connect-PnPOnline -Url <String> -AppId <String> -AppSecret <String>

The other two enhancements we are thinking are use site design and utilize PnP template. At this time, we are enhance the Office 365 site self-provisioning process to support both SharePoint online and SharePoint on-premises site creation process. We will share the architecture and implementation in the future.

No comments:

Post a Comment