Don’t Stomp My Configs - Dealing with Sitecore configuration on a multi-tenant platform

One of the big buzzwords of today is micro-services. A micro-services based architecture describe a system (or systems) made up of many, very lightweight, independently deployable services (Usually RESTful HTTP services), with very little interdependencies. Each service is usually deployed through a Continuous Delivery/Deployment pipeline and is usually designed to be updated many times a day with zero down time. The term conveys thoughts of testability, scalability, reliability, and velocity.
Sitecore was NOT designed this way.
Even when the Sitecore platform is scaled out into separate Content Management and Content Delivery servers, most components are expected to be deployed to all sites/application pools for everything to work. This architecture can be a real headache any time you have any multi-tenancy (more than 1 team working on more than 1 site). Even when we can deploy each component separately into these shared app pools, things can get very fragile because all teams are sharing the same memory space, app domain, bin directory, and configurations. It is virtually impossible to make this work without very close collaboration between teams and some establishing ground rules on what components and what versions of components to use, and a share vision for configuration management.
Here are some rules to consider:
  1. Create a repository of components/assemblies that all teams will pull from. My preference would be a private NuGet Repository. This can be as simple as setting up a network share, hosting a NuGet Site on your internal network, or using a 3rd party NuGet server. To learn more go to https://docs.nuget.org/create/hosting-your-own-nuget-feeds/.
  2. NEVER update any of the out of the box Sitecore configuration files unless there is absolutely no other options ESPECIALLY the web.config. By doing this it makes Sitecore maintenance and upgrade significantly simper. If you ever do find yourself with no other choice but to update an out of the box config make sure it is clearly documented in comments what you did and why. For Example, This is required for the Sitecore LDAP module:
    <roleManager>
    ...
        <!-- BEGIN CUSTOMIZATION: Add the LDAP Role Provider to the Asp.Net Provider List -->
        <add name="ad" type="LightLDAP.SitecoreADRoleProvider" connectionStringName="ManagersConnString" applicationName="sitecore" username="[put the username here]" password="[put the password here]" attributeMapUsername="sAMAccountName" />
        <!-- END CUSTOMIZATION -->
    </roleManager>
    
  3. Avoid HTTPModules!! Sitecore does a lot of crazy stuff in it’s own HTTP Module (NEXUS). The most important thing to note is that Sitecore does not really honor the purpose of each event. There is way more happening in the BeginRequest event that I think was ever intended. In may cases the HTTPContext is so manipulated when other events occur, you will get very strange results.
  4. Create Custom Pipelines that other teams can extend. This is very powerful and allows teams to build off of other teams customizations. We found this especially useful for bootstrapping configurations such as:
  5. Avoid WebActivatorEx and any like technology that you cannot control the order of execution. I have found that adding processors to the initialize pipeline is almost always better than magical bootstrapper technologies.
  6. Do not create custom web.config sections, use Sitecore style config sections instead. This type of config section can be loaded as a include patch config. see: http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2011/02/the-sitecore-aspnet-cms-configuration-factory.aspx
  7. Assign each team a set of folders that all their assets must reside to avoid file collisions.
  8. Assign each team a set of folders in the content tree where their Sitecore assets must reside.
  9. Always code everything as if you are go to release it into the Sitecore market place. Assuming you have no idea how will be using your components and how they will be used will make you code much more defensively. If one of your components throws an error, log it with a message that will made sense and make sure it doesn’t block other processing. Your code should behave like it is a guest in someone else's house and never assume it can takeover or that it is more important than any other component in the system.
I'd love to hear other rules/tactics that teams have used successfully. As always comments are welcomed and appreciated.
No comments

No comments :

Post a Comment