This week, Ben Curry—SharePoint MVP, SharePoint guru, and guest columnist—put together some great thoughts about a topic that should be at the top of everyone's list when it comes to deploying any kind of customization (e.g., custom code, master pages) to SharePoint solutions (i.e., SharePoint Solution Packages—WSPs). If you don't use solutions to deploy your customizations, things quickly go south. When I discuss SharePoint governance with clients and we look at the topic of governing development and customizations, I tell them that best practice #1 is requiring that developers provide solutions. By the way, you can learn much more about best practices and bad practices to avoid at the Best Practices Conference later this month. Ben did a fantastic job of laying out the case for solutions, so let me hand over the "pen" to Ben without further ado.
I remember Steve Ballmer screaming "developers, developers, developers" back at Microsoft TechEd. (I think it was TechEd. I don't remember the year.) That's what I feel like when I meet with clients talking about Best Practices - SOLUTIONS, SOLUTIONS, SOLUTIONS! Just say yes to solutions. Maybe I can get Todd Bleeker to do the SOLUTIONS rant and record it! That would be awesome.
So if solutions (i.e., SharePoint Solution Packages—WSPs) are so important, why don't all developers use solutions? Because they either don't know how, think it's too difficult, or don't want to take the time to package them. Before we look deeper into this bad practice of not using solutions, let's look at WHY it's a bad idea. First, let me describe a scenario I've been through multiple times with clients in the real world:
Your SharePoint Server is "toast," or worse—the whole farm is "toast." Luckily, you followed the best practice of scripting your farm install, so you restore your databases and script the servers back to life, but you get NOTHING when you browse to the site. You check IIS, all of the Web applications and app pools—they look fine. SO, you monkey with the install, still – nothing. Argh…
OH! You forgot you had a custom site definition. So, you copy the site definition from a backup. You restore it to a temporary server, go make coffee, and play some Tomb Raider while the server restores. The page renders.
What? Now, you have lots of Web part errors. Oh, the Web parts were all manually installed. But, they don't work correctly after you get them back installed. Argh…
OH! They have dependent features that aren't installed. OK.
You get the features back and no images? What? Are you kidding? Arghhhhh…
Oh, you discover that the custom site def has images that you now have to copy.
So you feel like we're almost there, except you have web.config changes to make, but at least the server is up.
OK now imagine this on a large scale and add lots of site definitions and features over multiple servers. One more thing, what if you needed to remove and/or upgrade items that were already deployed? How are you going to consistently remove it on all servers in a farm? It's like hacking through the briars with a tire iron…
While it might seem faster to simply deploy 'stuff' directly to the server, the long-term supportability is really going to suffer. The problem we have encountered again and again is that people have had initial success manually deploying artifacts, but over time as more items are deployed to larger number of web applications and more servers, inconsistencies arise. These problems can be very difficult to diagnose because they are inconsistent, only occurring on the servers and web apps that have not been maintained correctly. The process of elimination to locate the offending items is often lengthy and the solution is the creation of WSPs, which should have been created in the first place.
If WSPs offer so many advantages, the obvious question that arises is, "Why don't people always use them?" The answer is that creating a WSP will add extra steps to the development and deployment process. In the initial stages of SharePoint implementation, it seems simple to use other methods, bypassing the learning curve that WSPs require. Consider the following situation, which is based upon multiple real-world incidents:
A single web part is developed using strict development best practices. That web part will require the following file and configuration changes:
- A .dll to be deployed to the web application BIN directory so that it can implement code access security.
- A .webpart XML file that will specify the .dll, namespace, and class for the Web Part and defines properties for it.
- A Feature.xml file that is one of two files used to copy the .webpart XML file to the Web Part gallery of the site collection.
- An Elements.xml file that is one of two files used to copy the .webpart XML file to the Web Part gallery of the site collection.
- A safe control entry for the web application's web.config file that grants permission for the Web Part to run.
- Code access security policies that define what the Web Part will be allowed to do.
When the number of servers and web applications is relatively small, it seems easier to make these changes manually than use a WSP. Unfortunately, as the number of servers and web applications increase, the process rapidly becomes more complex. Consider our simple Web Part example: It requires six actions to deploy to a single web application on a single server. But if we increase the number servers and web applications to three each, the number of changes increases to 36:
- A .dll to be deployed to the web application BIN directory so that it can implement code access security. (Deploy to 3 web app bin directories on 3 servers = 9 changes.)
- A .webpart XML file that will specify the .dll, namespace, and class for the Web Part and defines properties for it. (Deploy to 12\TEMPLATE\FEATURES on 3 servers = 3 changes.)
- A Feature.xml file that is one of two files used to copy the .webpart XML file to the Web Part gallery of the site collection. (Deploy to 12\TEMPLATE\FEATURES on 3 servers = 3 changes)
- An Elements.xml file that is one of two files used to copy the .webpart XML file to the Web Part gallery of the site collection. (Deploy to 12\TEMPLATE\FEATURES on 3 servers = 3 changes.)
- A safe control entry for the web application's web.config file that grants permission for the Web Part to run. (Change the web.config file for 3 web applications on 3 servers = 9 changes.)
- Code access security policies that define what the Web Part will be allowed to do. (Change the web.config file for 3 web applications on 3 servers = 9 changes.)
Here are three more real-world lessons learned that should be mentioned:
- These problems aren't limited simply to Web Parts and related files. Items as simple as images and as complex site definitions (i.e., the blueprints that detail the creation of SharePoint sites) are all affected by improper non-WSP deployment. Site definitions, field types, event receivers, workflow, and features all must be deployed via WSP. In addition, Cascading Style Sheet (CSS) files, .aspx pages, and master pages will need to be deployed via WSP if they are to be used farm-wide. As a general rule, if the item in question will affect the entire farm it will likely need to be deployed via WSP.
- WSP needs to be used consistently. A commonly encountered problem is that someone deploys a .dll via WSP, then manually replaces it as a bug fix. When a new server is added to the farm and the old WSP is deployed, the servers are out of sync. Similar problems could arise if it becomes necessary to rebuild a server.
- Using WSPs and features can make deploying dependencies much easier. Consider the AJAX web.config feature that's available for free from CodePlex. The feature will automatically make the required web.config changes to allow AJAX Extensions to be used in SharePoint. WSPs can greatly simplify disaster recovery situations, creating test and development environments that mirror production or multiple geographically disparate SharePoint implementations. This can be enhanced further by the creation of a master script that adds deploys all WSPs consistently for the entire farm.
Thanks to Jim Curry for helping with the 'softie' part of this discussion. While I'm not a developer, I'm lucky to be surrounded by some top talent. You rock, Jim!
You can find more from Ben Curry in the MindSharp Blogs website.