Recently I was asked for my opinion on an article by a friend Peter Gfader. In his article Peter talks about automating the creation of a deployment package using MSDeploy. Along a similar line, I am regularly queried as to my opinion on what I see as the contrasts between TFS Deployer and MSDeploy. I’ve finally decided to distil these thoughts somewhat to provide a consistent expression of my opinion.
The approach taken by MSDeploy is very similar to the database deployment model taken by the Visual Studio Database tooling. It uses the project state to create a set of configuration and artefact descriptors which it then is able to compare to a target and generate a change script. This includes things like configuration setting transforms, artefact deployment, IIS setting changes etc. There is no need to have two IIS instances to compare, as Peter points out quite well you can simply have the settings packaged into a zip file with a specific format which can then form the basis of a later deployment comparison.
The first difference between the two tools is that TFS Deployer does not attempt to create a deployment package. It assumes a deployable unit is generated as part of the standard build process. This could be by any means appropriate to the tool set that is used by your organisation. As a personal preference, I err towards the use of WiX and the Votive tooling. This allows me to put together an exact specification of the deployment unit I’d like. I have had many clients where this has not been appropriate, and recognise the need for automation in this space and see Peter’s solution as quite useful for this purpose.
TFS Deployer operates primarily as a way of managing two important items that I feel MSDeploy does not yet deal with elegantly. The first is the automation of the deployment action as an operation separate to the build. As MSDeploy is instigated using an argument supplied to the MS Build engine, or as a separate tool it appears to encourage the usage of one of two possible approaches. Either couple the build and deployment actions so that the deployment is completed immediately as part of each build (which I strongly discourage) or specify a build that does no more than call MSDeploy with the correct arguments to begin the deployment process. While the second approach is agreeable in so far as it separates build and deployment actions, it too has some issues that remain to be addressed.
The primary issue I have with creating a build to initiate a deployment is that to action a successful deployment you first need two pieces of information:
- What am I deploying
- Where am I deploying to
There are a couple of ways to deal with this using a separate build template. One is to define a build for each environment which can quickly become annoying, especially without a meaningful grouping mechanism for build definitions. Another is to define a single build in which the parameters specifying the two above items are injected at execution time by the build initiator which I feel does not provide significant value over the manual initiation of MS Build itself due to the human error factors it introduces.
So where does TFS Deployer fit into this picture? The primary benefit of using TFS Deployer is that it takes the above pieces of information and makes them something you only need to think about once. By defining a trigger – in most cases the change in build quality, and a mapping of trigger to a specific target environment TFS Deployer allows you to execute a deployment with a single click, rather than a click and some manual configuration.
The second benefit TFS Deployer provides is that it is built around the use of PowerShell. As the defacto server management technology within Microsoft OSes, the use of PowerShell to script your deployment actions ensures that your deployments are able to be quickly understood by your operational teams as well your development teams. It also – depending on your packaging choices, is able to help limit the amount of change needed on your target servers to support deployment. This is done by using the PowerShell remote execution features to initiate the deployment on the target rather than needing a TFS Deployer instance on the machine itself.
So if these are the features, are the two products mutually exclusive? The answer is no, and nor should they be. Where MSDeploy has strengths you should utilise them, such as described in Peter’s article. However I say the same of TFS Deployer. Why attempt to bend, or wrap the usage of MSDeploy with custom code or build definitions when TFS Deployer provides a simple and effective interface for managing both the trigger and target mappings for your product.