The reason I've decided to tackle this problem, irrespective to SharePoint, is because I believe that they don't have to. With technologies like MSI, msbuild, TFS, Web Deploy, ClickOnce, and SharePoint solutions, Microsoft has given us tools to make this daunting task easier. However, that's apparently not enough, since it really just makes deployments suck less.
These technologies, and so many other third party tools like them, are great at taking a finished product and making it portable. But in my opinion, that doesn't solve the underlying problem of deployment's difficulty. They make deployment paradigms like XCOPY or Emailing ZIP files to yourself finally obsolete. They remove the onus of a lot of the manual "touching" you have to do in each target environment. They at least force the awareness of the deployment.
Don't get me wrong: these tools are awesome. But they're not the complete solution.
In fact, there is not currently, nor in my opinion will there ever be in the future, a magical all-encompassing deployment tool. Like with anything else in technology, there is a leapfrog effect. In the same way that new, memory-hungry software drives the hardware industry to crank out faster and faster processors, the complexity of applications will always be a step ahead of the elegance of deployment tools.
It's not a new panacea we need; it's a new paradigm.
The great thing about a paradigm shift is that its adoption is completely up to us; we don't need to wait for Microsoft to solve the problem. We can solve it right now.
I still remember my first "deployment." I use quotes because it wasn't really a deployment; it was more of a slow matriculation of my code to development, test, and production servers. Instead of having a nice neat method of deploying my entire application, I just sort of oozed parts of it, like stubborn toothpaste at the bottom of a near-empty tube, to where it needed to go.
It was an InfoPath 2003 / SharePoint 2003 solution, both "V-ones" of their respective technology families at the time. This implied that there was little guidance from Microsoft and even less documentation. Additionally, this was also before some of the aforementioned tools that allow for continuous integration or solution packaging even existed.
Of course, I did what I could to streamline this process. I built MSI's and had batch scripts that automated a lot of work for me. But using these then-best practices still left me manually copying assets, updating configuration files, uploading templates to document libraries, etc. late into the night. (I actually used to clear my calendar, both day and night, on the eve of every deployment.)
My deployment script? Remote into the server, drop DLLs into the GAC, and do an IIRESET. My test script? Have the users hit the site and see if it works. Our client sponsor received so many Emails from our poor users ranging from forlorn to frightful that he came over to my desk and yelled: "This is not how we deploy software!" To this day, I'm still trying to figure out exactly how we do deploy software.
I've been painfully aware that not a lot has changed since then, because we, although now armed with a lot of deployment-enhancing tools, still have the same paradigm: code it first; deployment is an afterthought. Since it technically comes last, (either during an agile iteration loop or at the bottom of the waterfall) it's therefore considered last as well. I'll bet that the elegance of a deployment, across any survey of software projects, is directly proportional to how much money is left in the budget when the final feature is signed off on.
And guess what? That amount is probably almost always red. What does that say for deployment strategy planning?
If I had to write this book in one sentence, like most of you would probably prefer, it would be thus: "Deployment is not an appendix of an application; it is not a feature of a solution; it is a requirement, if not the very core of the architecture." For every single facet of an application, every line of code, every asset, everything right-click-add-to-project'ed, we need to be asking ourselves how this particular molecule of our system will be deployed before we write it, add it, or include it.
A slick, automated deployment procedure can be just as sexy as a sick Silverlight UI with animations, drop shadows, gradients, etc. Whereas end users will be impressed with your team's development skills, administrators will be equally impressed with your deployment architecture. If you can walk into a client with a WSP, and in five minutes' walk out with a fully provisioned, fully populated site, you'll be just as big a rock star as the designers.
Henry Ford was a genius. I like to think that he was watching cars being assembled by hand one day, looking at his numbers, thinking to himself that there had to be a better way. So he invented the assembly line and changed the world of manufacturing forever. He didn't give his workers better tools. He didn't experiment with using more dynamic materials. He changed the entire paradigm. He considered deployment first, and made the construction process follow the model.
Workers stopped building cars. They started building doors, engines, steering wheels, and brake lamps. Once each component was completed, it was attached to the in-progress vehicle. Deployment pervaded the entire construction process. It drove (pardon the pun) the project plan. It was more efficient and less error-prone than "water falling" each car from scratch.
This is what we must do for software. As long as we implement, plan, or at least consider deployment at the beginning of a project, milestone, or development cycle, we will keep ourselves from architecting or building components that are difficult to deploy. Instead of trying to minimize deployment headaches, we can simply avoid them. That's why I ended my above one-sentence recapitulation with deployment being at the core of the architecture: when designing our solution, we can choose methodologies or plan components that are easily transportable from environment to environment.
Let's put this into the context of SharePoint. A great example to use for any hypothetical SharePoint development scenario is the quintessential unit of functionality in a portal: the web part. If you ever find yourself working on a SharePoint project for which there are no web parts, the question needs to be asked if SharePoint was the correct architectural decision for it.
Will this remain the case in SharePoint 2013? I have heard it said that web parts are now "dead." I'm still personally picking up the pieces from Silverlight's deprecation, and doubt I have the emotional fortitude to withstand web parts going away as well. So either you will find me huddled in the fetal position in the server room, drooling and sobbing incoherently, or my hunch that web parts will continue to dominate SharePoint intranets will be correct.
2013 is bringing apps and their Store to the SharePoint party, which have their own deployment considerations. We'll hit on this later. But you'll find that code and techniques are going to be exploring are more pursuant to the paradigm that we first learned in SharePoint 2010 / Visual Studio 2010 and will deepen with in SharePoint 2013 / Visual Studio 2012.
Now before we even start thinking about how to build a web part, my entire point is that we should consider first about how to deploy it. And "Well, just use a Visual Studio 2012 SharePoint project." is not the complete answer. It's a good starting point, and it's a good ending point, but there's a vast middle ground of custom architecture and infrastructure that we need to consider before we write a single line of code.
So after we create our TFS project and our Visual Studio solution, we need to start making some decisions. One of the first questions to ask is: "Where does the data come from?" For most web parts, the answer to this primordial question is usually chosen from two finalists: a SQL database or a SharePoint list.
Unless of course there is some glaring reason to use one over the other (relational data for a database or desire for on-the-fly schema updates for a list), let's make this architectural decision based on deployment. Whenever possible, I'm going to opt for the list. The same provisioning strategy we'll use to push the web part (which is Visual Studio) can be also be used to build and deploy the list.
If our architecture called for a database, we'd be taking on the onus of adding several more dimensions to our deployment: the need to have a database tier in our application (and the backing SQL environments), a SQL script to deploy the database's schema, web.config modifications to store the connection string, and an Entity Framework data access layer.
If we use a list, all we need beyond the list itself is the data access layer. Even if we throw SPMetal at it, that logic will be either in the same DLL, or a separate assembly that the solution package can deploy for us. Since everything is SharePoint, we can follow the standard deployment model and enjoy a wonderful right-click-deploy development experience. As you can see, considering deployment as part of your architecture can save you a lot of time and reduce a lot of complexity.
But if you simply need the power of a full SQL database to back your web part, or have a legacy system to connect to, or don't require the free administrative user interface that you get out-of-the-box with SharePoint lists, then by all means go with the database. Sometimes just having more than one logical component that could use a database legitimizes adding this dimension.
And even if you need to travel this more complicated route through your application, you've at least put some deployment forethought into your architecture, and can start planning for it immediately. Trust me: you won't miss having the following inner monologue after a deployment: "It doesn't work in prod! Could it be...oh shit, I didn't update the connection string!"