Sitefinity Search
on Microsoft Azure

Aug 29

Since forever Sitefinity had a little secret that search did not work on Microsoft Azure. For two years I have kept thinking they'll sort it eventually. Then recently I found out that the new site map generator didn't work either.

Update January 2015:

As of 7.3 you now have Azure search as the option for your search service in Sitefinity. Also the sitemap generator is no stored in the database and cached in memory so no physical file is created thus eliminating the need for the details in this post.

As a developer I love Sitefinity as a platform. I also love Microsoft Azure as a platform. But the two aren't quite happy chappies together. The published disagreement is that Sitefinity search does not work on Azure and we all know that. (Only if you read the documentation.) But just recently the new sitemap generator also does not work.

I started posting forum posts to help keep the subject in the fore front and then I read a post which mentioned about trying a search solution that did not write to the file system.

What appeared to be the problem, was that Azure does not set Write permissions on the file system expect for the App_Data folder. (Or I as you will see soon, the Web Deploy only sets write permissions on the App_Data folder). Here I am talking about the Windows file system because you may be thinking, "I upload files all the time!", but that is via FTP and the account you use there is different to the one that runs the website\AppPool. (Being an ex Server Administrator this all made sense to me so don't worry if it doesn't to you. Its not important)

On most hosters you have an option to set the permissions. You go into the control panel and tick a box or two. But this is not available on Azure.

My first thought was to use IIS Remote Admin and remote onto my Azure website and set the folder permissions. (Read this post if you don't know about doing this). Bad news though. That functionality is not available. So I started looking at how to set ACL permissions on the Azure website.

I found 3.
One was via powershell.
Another by manually manipulating a web deploy bundle.
But the best, (for me), was an article by Sayed Ibrahim Hashimi. He wasn't writing about Azure directly but he did show how to add ACL permissions for my web deploy to my solution.

I won't repeat Sayed post. (You should read that for the detail.) You add a .wpp.targets file to your solution which can set the access permissions. When you publish your site to your Azure websites you will then get the access permissions required.


Disclaimer

I have only worked on this, this evening. Though everything seems good, further testing may bring up some gotcha's. But I am hoping that other people, (you), try it and feed me back information. I have also contacted Sitefinity for there input and I will update this post with their response.


Fixes


I added Write, Read and Modify permissions to the /App_Data/Sitefinity/Search folder.
Do ensure that the folder exists before hand.

To fix the sitemap generator I added a folder named data to my site and set the same ACL's on that folder. At this stage I am not to sure about setting permissions on files, especially if they don't exist. I could just set Write permissions at the root of the entire site I guess but I am happy with this.
(Don't forget to update your Google sitemap location in the web master tools)

Below is my added targets file. It should be named {Your.Project.Name}.wpp.targets. But otherwise you can copy what I have below.


<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 	<Target Name="SetupCustomAcls" AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
    		<ItemGroup>
 			<MsDeploySourceManifest Include="setAcl">
 				<Path>$(_MSDeployDirPath_FullPath)\App_Data\Sitefinity\Search</Path>
 				<setAclAccess>Read,Write,Modify</setAclAccess>
 				<setAclResourceType>Directory</setAclResourceType>
 				<AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
 			</MsDeploySourceManifest>
 			<MsDeploySourceManifest Include="setAcl">
 				<Path>$(_MSDeployDirPath_FullPath)\Data</Path>
 				<setAclAccess>Read,Write,Modify</setAclAccess>
 				<setAclResourceType>Directory</setAclResourceType>
 				<AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
 			</MsDeploySourceManifest>
 		</ItemGroup>
 	</Target>
 	<Target Name="DeclareCustomParameters" AfterTargets="AddIisAndContentDeclareParametersItems">
 		<ItemGroup>
 			<MsDeployDeclareParameters Include="SearchSetAclParam">
 				<Kind>ProviderPath</Kind>
 				<Scope>setAcl</Scope>
 				<Match>^$(_EscapeRegEx_MSDeployDirPath)\\App_Data\\Sitefinity\\Search$</Match>
 				<Description>Add write permission to the Search folder.</Description>
 				<DefaultValue>{$(_MsDeployParameterNameForContentPath)}/App_Data/Sitefinity/Search</DefaultValue>
 				<Value>$(_DestinationContentPath)/App_Data/Sitefinity/Search</Value>
 				<Tags>Hidden</Tags>
 				<Priority>$(VsSetAclPriority)</Priority>
 				<ExcludeFromSetParameter>True</ExcludeFromSetParameter>
 			</MsDeployDeclareParameters>
 			<MsDeployDeclareParameters Include="DataSetAclParam">
 				<Kind>ProviderPath</Kind>
 				<Scope>setAcl</Scope>
 				<Match>^$(_EscapeRegEx_MSDeployDirPath)\\Data$</Match>
 				<Description>Add write permission to the Data folder.</Description>
 				<DefaultValue>{$(_MsDeployParameterNameForContentPath)}/Data</DefaultValue>
 				<Value>$(_DestinationContentPath)/Data</Value>
 				<Tags>Hidden</Tags>
 				<Priority>$(VsSetAclPriority)</Priority>
 				<ExcludeFromSetParameter>True</ExcludeFromSetParameter>
 			</MsDeployDeclareParameters>
 		</ItemGroup>
 	</Target>
   </Project>


I hope this is a good solution as it is the only one I have seen so far.


Update: 7th Sept

First update is around a an error when trying to publish. You may get something along the lines of 'ERROR_EXCEPTION_WHILE_CREATING_OBJECT'. It's in capitals so it must be serious. (Or some old const naming standard). What I found is that the folders Search and\or Data were empty and if you know your web publishing, a empty folder isn't deployed and this is cause of the error. The fix. Put a dummy text file in there.

I did get a response back from the Sitefinity team and they said "yeah this is fine, but be aware that this won't work in a scaled environment." Which is true for Sitefinity supported configurations but not me.

When talking about this you need to understand what Azure environment you are in. Azure Cloud Services the supported Sitefinity environment or Azure Websites the not supported environment.

Azure Cloud Services

In Cloud Services you have Web roles and Worker roles and you can scale these out separately. Its really good if you need that type of flexibility for your app. But there is no shared disk and so you must put your config in the database. Search doesn't work as it writes files to the disk.
Though in saying that, Azure Files is now released and you may be able to use that to get it going.


Azure Websites

But Azure websites is different. The files for Azure websites are stored on a shared disk. (Actually they got Azure Files created for them in the first place.) So no matter how many instances I have they all still use the same physical files on the shared disk. So yes, I have a scaled Sitefinity website with my config files not stored in the database, Search working and just to prove a point I have some images stored in the File System. All is working.

Still.....

I can't assure you that this is faultless. I can't test it properly. I just don't have the time. I need to take into account caching and the fact that Azure Websites is 'sticky session enabled'. (Which is a good thing if you want me to take a side on it.) Yet it makes testing a bit harder.

What about caching you ask.


Sitefinity has memory cache and if you publish a page on one node it won't remove it from another. You need to use the Sitefinity Load Balancing Module!

Or I could use the Azure Service Bus, set up a Publish\Subscribe between my instances and send messages about pages to be removed from the cache. I have that working but again it's all POC at the moment. But I am sure there is more to be considered. I will have a better look at the Load Balancing module and some stage.

I will keep working on it in my spare time and I will do a full post on running Sitefinity on Azure Websites in the near future I hope. Or perhaps Sitefinity will just take my POC and support Azure Websites.


Update 27 Sept 2014

Good news. Sitefinity now have Search support on Azure as a work item. You can read the comments and hopefully follow its progress.


Darrin Robertson - Sitefinity Developer

Thanks for reading and feel free to comment
Darrin Robertson


Leave a comment
Load more comments

Make a Comment

Please type the code above

comment-avatar