Friday, 12 July 2013

Deploying SP2013 provider-hosted apps/Remote Event Receivers to Azure Websites (for Office 365 apps)

Before SharePoint 2013, we were all used to the idea of custom code running on SharePoint servers. However, this changes with SP2013 – Microsoft are either forcing us (Office 365) or steering us (on-premises) to run such code off the SharePoint boxes. And you can understand why – frankly Microsoft have no chance of providing a stable Office 365/SharePoint Online platform if it has everyone’s custom code running on it. So, SharePoint 2013 allows event receiver code to run on a remote server. This post looks at deploying Remote Event Receiver components to an Azure Website for a SharePoint site running in Office 365. Since RERs take the form of a provider-hosted app in SharePoint 2013, everything I write here also applies to a provider-hosted app too. Some changes would be required (to code and configuration steps) to achieve the same for an on-premises farm, unless you have configured that environment to trust ACS. Before we dive in, here’s where we are in my overall app series:

  1. SharePoint 2013 apps – architecture, capability and UX considerations
  2. Getting started – creating lists, content types, fields etc. within a SharePoint app (provisioning)
  3. Working with data in the app web, and why you should
  4. Access end-user data (in the host web) from a SharePoint 2013 app
  5. Rolling out SharePoint 2013 apps to the enterprise - tenant scope and PowerShell installs
  6. Azure is the new SharePoint ‘_layouts’ directory
  7. “Host web apps” – provisioning files (e.g. master pages) to the host web
  8. “Host web apps” – provisioning fields and content types
  9. Deploying SP2013 provider-hosted apps/Remote Event Receivers to Azure Websites (for Office 365 apps) [this article]
  10. Working with web parts within a SharePoint app

Why would I deploy this stuff to Azure?

I think a good option for SharePoint remote code (e.g. some provider-hosted apps, Remote Event Receivers etc.) is to host this code on the “Azure Websites” offering – this is compelling because it’s free, quick and easy to spin up, and you don’t need to provide any in-house servers (with the resulting high availability, scalability, backup/restore and performance work which is required). Another significant factor is that you don’t need to involve your gateway/networks team in getting the website (which hosts your provider-hosted app pages and/or WCF service for your Remote Event Receivers) published (on SSL of course) and accessible externally - e.g. through UAG, or whatever your perimeter device may be. Azure is already outside of your firewall and accessible/addressable over the internet of course, and Azure Websites have automatic SSL support on the default domain (which is *.azurewebsites.net). If you want to use a custom DNS host name instead (e.g. code.MyCompany.com) then you can do that too, with some extra steps.  In general, using Azure Websites is a great way to sidestep many of the infrastructure roadblocks which can derail you.

What about building my app/RER as an auto-hosted app?

It’s a fair question, since not only do auto-hosted apps for Office 365 “just work”, but in fact they actually run on Azure Websites underneath. So why would you not just do that? Well, this works great for demo and proof-of-concept code. But personally I wouldn’t feel comfortable recommending this architecture to a client for production, and I notice others feel the same way. Frankly there is too much “black box” going on with auto-hosted apps – there aren’t really any knobs and dials right now, and technical details are scarce (e.g. scale limits, scale-up possibilities). Also, anyone building apps for the Store will note that auto-hosted apps cannot be sold there, and it’s unclear if they will be in the future.

So, I prefer the more manual approach of deploying to Azure Websites myself. The benefits I get are:

  • I can scale up from Azure Websites (shared) to reserved hardware (e.g. if my app is more heavily used, or uses more processor/memory than anticipated)
  • I can use Azure’s AutoScale capabilities (currently in preview) to do this automatically based on rules I set (e.g. processor thresholds)
  • I have better monitoring of my app
  • I can make changes to the Azure pieces of my app without redeploying the SharePoint pieces
  • I can publish in many different ways (e.g. FTP, WebDeploy, Continuous Deployment from TFS, git etc.)
  • I can examine the files in Azure to do trouble-shooting by opening an FTP client

How does my O365/SP2013 permutation fit in with this article? What other things should I think about?

Permutation Consideration
Office 365 + app in Azure Websites The focus of this article. As detailed above, quite similar to auto-hosted apps but with way more control.
On-premises + app in Azure Websites You’d need to make some changes to the code/process discussed here. Effectively you need to configure high-trust/S2S authentication instead, (rather than OAuth to ACS) and ensure you’re using the correct TokenHelper methods or equivalent custom code. An alternative to S2S could be on-the-fly auth.
Office 365 + app in on-premises server Can be attractive because could easily integrate with other on-premises applications/data. However, usually more complex due to operational I.T. challenges listed above. Solvable with techniques like Azure Service Bus, BCS, or simply exposing your data through custom services (e.g. WCF) from on-premises to the internet/DMZ.
On-premises + app in on-premises server Fairly simple because everything is behind your firewall. Requires S2S authentication configuration or on-the-fly auth.


What kind of code might this be?

Examples of such remote code in SharePoint 2013/Office 365 are:

  • Remote event receivers
    • List events (e.g. ListAdding)
    • ListItem events
    • Web events
  • App events
    • AppInstalling/AppInstalled
    • AppUpgrading/AppUpgraded
    • AppUninstalling/AppUninstalled
  • Other app code – i.e. the entire set of functionality in a provider-hosted app

What you need – a summary

Here are some of the key things you need:

  • A website to be created on Azure Websites
  • A solution which uses a Remote Event Receiver – for the first time you do this, I recommend using something guaranteed to work rather than your own code (to avoid getting the code and/or RER declaration wrong). I used the BasicDataOperations SP2013 provider-hosted app on MSDN
  • To have registered the app with AppRegNew.aspx on your SP2013 environment or Office tenancy – this creates a new App Principal “known” to the environment.
  • Within the app:
    • All the URL references in the app to be updated with absolute URLs pointing to your Azure website e.g:
      • The declaration of the Remote Event Receiver
      • The app start page listed in AppManifest.xml etc.
    • The ID of the remote web application (i.e. the App Id) listed in the AppPrincipal section of the AppManifest.xml
  • For the Visual Studio project which represents the remote web (rather than the app itself):
    • The web.config to be updated with the ClientId and ClientSecret (note there is a big gotcha when running site on Azure Websites – the web.config is not used for AppSettings. Instead, use the Azure Management Portal to supply these as per the steps below!)
    • It to be published to your Azure website – there are many options for this, but I like WebDeploy (shown below)

The detailed process

Here’s a more detailed run through of the process - I’m focusing very much on the infrastructure/configuration here rather than the code, although I do call out some things:

  1. Create or obtain your solution. As with any SharePoint app with remote components, in the BasicDataOperations app I’m using, there are two Visual Studio projects:
    1. One for the SharePoint app
    2. One for the remote components (i.e. this is the ASP.NET website which hosts the WCF service for the Remote Event Receiver)
  2. Register your app with AppRegNew.aspx (i.e. the page which can be found at /_layouts/15/appregnew.aspx), and make a note of the App Id and App secret:

    AppRegNew
    AppRegNew confirmation
  3. Create your Azure Website in the Azure Management Portal – make a note of the URL. In my case this is https://cobspdev.azurewebsites.net
  4. Update the SharePoint app project so that the URL references point to this Azure site:
    1. The RER declaration should look something like this:
      ** N.B. My newer code samples do not show in RSS Readers - click here for full article **
    2. The AppManifest.xml should look something like this:
      ** N.B. My newer code samples do not show in RSS Readers - click here for full article **
  5. Also ensure the SharePoint AppPrincipal section of AppManifest.xml lists a RemoteWebApplication, with the ClientId attribute set to the App Id (from the app registration):
    ** N.B. My newer code samples do not show in RSS Readers - click here for full article **
  6. [OPTIONAL] If you want to debug your remote code, you should set up a Service Bus instance on Azure and configure your SharePoint app project with it:
    1. Go to the “Service Bus” area within the Azure Management Portal, and create a new namespace for this app:
      App debug - service bus in Azure 
    2. Then click “Connection Information” for this namespace and view the details – copy the connection string:
      App debug - service bus conn string
    3. Finally, in Visual Studio go to the project properties for the app project (not the web project). Go to the SharePoint tab, and scroll to the bottom – ensure “Enable remote event debugging” is checked, and paste the Service Bus connection string into the textbox:
      App debug - configuring VS project
      If you need more information on this, see Update to debugging SharePoint 2013 remote events using Visual Studio 2012.

  7. Publish the ASP.NET website to Azure – I’m using WebDeploy here:
    1. Download the Publish Profile for your Azure Website:

      Download publish profile
      Download publish profile - save 
    2. Publish the app – importing the Publish Profile since this is the first time:
      Publish web app
      Publish web app - import   
      Publish web app - import - select file

      Publish web app - validate settings 
    3. Once the settings in the Publish Profile have been validated (as in the previous image), click “Publish” to deploy to your Azure site. You should then see a success message:

      Publish web app - publish success
      The remote components are now deployed to Azure.

  8. Since AppSettings are not pulled from the app’s web.config file in Azure Websites, we need to configure them actually in Azure. Go to the Azure Management Portal, and select your website. Click CONFIGURE, then scroll down to the AppSettings section – enter the ClientId and ClientSecret here:

    Azure - app settings  
  9. Publish the SharePoint app to Office 365 (by first publishing to the filesystem):

    Publish app 
    You’ll be presented with the dialog below – re-enter the details. I haven’t checked yet, but actually I’m not 100% sure this is necessary (for the Client ID and Secret) as web.config already has the values. But I suggest doing it anyway, since that definitely works :)

    Publish app - enter settings

    Publish app - files generated 
  10. At this point, the app is ready and can be added to the App Catalog in your Office 365 tenancy. Go to the  “Apps for SharePoint” library within the associated App Catalog site, and either upload the .app file conventionally, or drag in:

    Publish app - upload to app catalog
  11. Now the app can be added to a site:

    App install - in site
  12. Once the permission request has been accepted, the app is installed and can be run. Enter the app by clicking on it in the Site Contents page:

    App - in site

    ..and there is the BasicDataOperations MSDN sample app running in your Azure site, in all it’s ninja CSS and responsive design glory:

    BasicDataOperations

The point of course, is that you now have remote code running and have a location to host it.

Summary

In scenarios where your code must run “off-box” to SharePoint (such as Office 365), Azure Websites can provide a much easier way of doing this than with on-premises IIS servers. You can use Azure’s flexibility to scale up from shared to reserved instances if you find you need to. 

You have to consider if you are happy for your code to run there, and some considerations such as authentication/integration with on-premises systems could rule it out for you. Otherwise, it can free you from dealing with lots of infrastructure aspects (especially getting the website published externally), and so is a useful tool in the toolbox.

It also depends on what your code is – my overall feeling is:

  • If your only remote code is Remote Event Receiver code, Azure Websites is definitely worth considering
  • If you have a full provider-hosted app (with maybe RERs in there too), then consider either hosting on-premises if you can do a good job, or one of the even more “grown-up” Azure options

10 comments:

Dennis said...

"ninja CSS and responsive design glory" :-)

Great article, thanks! The best information I got was remote event debugging over Service Bus. That is some crazy technology.

Chris O'Brien said...

@Dennis,

Yep agree - it's pretty incredible when you think of the mechanics there! Kudos to the Azure and SharePoint Product Groups :)

C.

Nigel Price said...

Hi Chris
You say Azure is 'free' is that the case in a production environment or just in a dev environment ?

I thought you got charged by the minute now on Azure.

Regards

Nigel

Chris O'Brien said...

@Nigel,

Azure Websites is free. For more details on Azure options, see Windows Azure Execution Models.

Cheers,

C.

Mahmoud Hamed said...

Hi Chris,

Great article.

Regards,
Mahmoud

Andrew Burns said...

When I try to add the app to the site it won't let me - there's a warning box reading "Sorry, this app is not supported on your server." I'm not sure what I've done wrong

Andrew Burns said...

Ah, got it working. I had copied the AppPermissionRequests element from the blog post into my manifest. Removed it again, and it works...

sanjay joshi said...

Great article.

Can we use the same client ID and secret for the different different provider hosted app ?.

Or each time we need to create a different site for each app to authenticate based on client ID.

Because i am not able to put more then one client id and secret in created site in azure . ?>>>>>>

Chris O'Brien said...

@Sanjay,

No, I'm pretty sure this won't work. For one thing, I don't believe you can register two apps with the same App ID (either in AppRegNew.aspx or in the Seller Dashboard for Store apps).

Also, consider that the Redirect URI needs to be different for each app registration.

HTH,

Chris.

estebanv said...

Hello Chris

I am having big problems trying to debug RER via azure service bus, when I take a look at your screenshot to note down the connection string, it differs on my side, (maybe they updated the UI).

http://screencast.com/t/vTzViiq4

If I use that connection string (SAS), then debugging doesnt work I get these kind of errors:
http://sharepoint.stackexchange.com/questions/113850/there-was-no-endpoint-listening-at-service-bus-for-sharepoint-app-cannot-re

When I check some documentation here:
http://msdn.microsoft.com/en-us/library/azure/dn170478.aspx

It says: For example, if you create a Service Bus namespace called contoso.servicebus.windows.net, a companion ACS namespace called contoso-sb.accesscontrol.windows.net is provisioned automatically. For all namespaces that were created before August 2014, an accompanying ACS namespace was created.

any idea how to create it after august 2014?


thank you