Category: TFS Deployer

TFS Deployer Least Privilege

The original TFS Deployer attempted to access various restricted resources than effectively required it to run as an administrator user. Since some changes were made in February, Deployer can now be executed under a standard user account with some additional considerations which follow.

Team Foundation Server Permissions

The TFS Deployer service account must be a member of the Team Foundation Administrators server-level group on the server specified by the TeamFoundationServerUrl config setting. The permission to subscribe to Build Quality changes via SOAP is only granted to adminstrators. I am investigating a way to grant this permission at a more granular level.

PowerShell Execution Policy

TFS Deployer can execute Windows Command Scripts if you really need it to but PowerShell scripts are the preferred option. However, PowerShell is built to be secure-by-default and installs with script-running capabilities disabled. It is left for the user to enable scripts after PowerShell has been installed and can be performed by opening the PowerShell console as an administrator and executing either:

Set-ExecutionPolicy AllSigned ; # orSet-ExecutionPolicy RemoteSigned

The former choice will require you to sign all your deployment scripts in source control with a certificate trusted by the Deployer. Scott Hanselman has a comprehensive post on his blog describing the signing process. The latter choice will not impose this requirement because files retrieved from source control by Deployer are not marked with a zone identifier.

HTTP Namespace Reservation

TFS Deployer utilises self-hosted WCF over HTTP to subscribe to Build Quality Change events from TFS. This technique relies on the Windows HTTP Server API which requires the Deployer service account to have been granted rights to listen on the portion of the HTTP URL namespace it uses for event notification. By default only local administrators have access to the entire namespace and permissions must be granted using the httpcfg tool (on Windows XP and Server 2003) or the netsh tool (on Vista and Server 2008).

Using the netsh tool, from an administrator command prompt, the following command (as a single line) will grant rights to the appropriate URL for TFS Deployer (assuming you are using the default port number):

netsh http add urlacl url=http://+:8881/BuildStatusChangeEvent user=DOMAIN\TfsDeployerUser

Using the httpcfg tool is more difficult as it requires an ACL string in Security Descriptor Definition Language (SDDL). However, Dominick Baier has created a tool to simplify this process and I can recommend it.

Additional Permissions

All deployment scripts executed by TFS Deployer will be executed under the context of the service account unless the scripts explicitly contain alternate credentials. If the scripts copy files to a network share, configure a web site in IIS, or even upgrade the schema of a SQL database, ensure that the service account also has the minimum privileges to perform those actions too.

Any problems, questions, or suggestions… let me know.

Explaining new features in TFS Deployer

Since I began helping Mitch with changes to TFS Deployer to make it compatible with TFS 2008, I have slowly been adding small features that seemed useful in my work environment. However, unless you’ve read the code, you probably wouldn’t know they exist so I’ll describe them here.

Quality Mapping Wildcard

TFS Deployer operates on executing scripts for particular build quality transitions. Normally transitions like “Test” to “Production” are common. However you may wish to have a script that runs when the quality is set to “QA” regardless of what is was before. You can now specify asterisk (*) in place of the value of either of the OriginalQuality or the NewQuality attributes in the DeploymentMappings.xml file to specify a match on any quality.

Retain Build

Team Build in TFS 2008 now has Retention Policies to clean out old builds. If you deploy a build with TFS Deployer you don’t want the policy deleting the build outputs. You may also want builds to become subject to policy again after you retire them from failed acceptance testing. You can add a RetainBuild attribute to a Mapping element in the D*M*.xml file. A value of “true” will mark the build to be kept upon successful execution of the deployment script. A value of “false” will unmark it, and an absent attribute will leave the retain flag alone.

Shared Deployment Resources

With multiple Team Builds defined and multiple deployment configurations you’re bound to end up with scripts with common components you’d like to refactor out to a shared location. You can now specify a TFS path (ie $/MyProj/TeamBuildTypes/Shared/Deployment/) in the TfsDeployer.exe.config file in the SharedResourceServerPath application setting. If provided TFS Deployer will get the files in this directory and place them in the same folder as the deployment script on each script run.

The first two features are in the latest release drop on CodePlex. The latter is only in the latest change set, so check the Source Code tab if you intend to use shared resources. Any problems, questions, or suggestions… let me know.

TFS Deployer and TFS 2008

Mitch Denny from Readify made two great tools available for Team Foundation Server last year. TFS Integrator provides Continuous Integration for TFS by registering for check-in events then triggering Team Builds and Dependency Replication. TFS Deployer provides automated deployment for TFS projects by registering for build quality change events then executing associated PowerShell scripts. Both of these tools were developed for TFS 2005.

TFS 2008 has just RTMed and it already includes check-in triggered builds in the box so TFS Integrator is less useful (except maybe the Dependency Replication but this can be done via other methods). TFS Deployer, though, is still very useful in a TFS 2008 environment… assuming you can get it to work.

TFS Deployer was originally developed against the TFS 2005 client libraries and, of course, we’ve uninstalled VS and TFS 2005 from most of our machines already so Deployer just falls over because it can’t find the libraries.

TFS Deployer is not open-source (yet) so I can’t fix it myself. However, in a comment Mitch suggests using binding redirects in the TFS Deployer config file to enable TFS 2008 support. Unfortunately he doesn’t give specifics.

I decided to drop the TFS Deployer assemblies into Reflector and find the list of TFS libraries it uses so I could write the redirects. I updated the .config file and changed the build quality on some existing builds and happily discovered that it works. If you want to use TFS Deployer with TFS 2008, here is the section to add to the TfsDeployer.exe.config file:

<runtime>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<dependentAssembly>
<assemblyIdentity name=”Microsoft.TeamFoundation.VersionControl.Client” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />
<bindingRedirect oldVersion=”8.0.0.0″ newVersion=”9.0.0.0″/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name=”Microsoft.TeamFoundation.VersionControl.Common.Integration” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />
<bindingRedirect oldVersion=”8.0.0.0″ newVersion=”9.0.0.0″/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name=”Microsoft.TeamFoundation.Build.Common” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />
<bindingRedirect oldVersion=”8.0.0.0″ newVersion=”9.0.0.0″/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name=”Microsoft.TeamFoundation” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />
<bindingRedirect oldVersion=”8.0.0.0″ newVersion=”9.0.0.0″/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name=”Microsoft.TeamFoundation.Client” publicKeyToken=”b03f5f7f11d50a3a” culture=”neutral” />
<bindingRedirect oldVersion=”8.0.0.0″ newVersion=”9.0.0.0″/>
</dependentAssembly>
</assemblyBinding>
</runtime>

Code Camp SA: Mitch Denny

Mitch‘s presentation about “TFS Virtualization and Advanced Build Techniques” was my highlight for day one of Code Camp SA.

Mitch suggested that one of the major benefits of virtualizing Team Foundation Server was the ability to rollback the whole server at any point. While that is certainly helpful if the service packs don’t install right the first time, the benefit I’ve found personally is being able to pick up the whole VHD and drop it on another Virtual Server machine without any reconfiguration. Great for hardware failures.

Mitch also suggested getting a *big* server to host the virtual TFS and use the slack space to host additional virtual build servers. We toyed with a build server once and based on performance I figured a physical machine would be best but Mitch demonstrated a great idea combining multiple virtual build servers with a false TFS build agent to auto-redirect to a free, pre-cleaned build server.

In fact, the Readify team have some great TFS tools available to get the most from the system:

Mitch showed how, with these tools and some PowerShell glue, you can have a complete, automated process to go from a check-in, automatic build, to update dependencies, rebuild those, deploy for QA, then deploy to production. Nice.

With a lot of VB in our production code we’ve been held back from a CI system by the MSBuild secondary reference issue but a quick chat with Mitch after the presentation cleared that up:

Me: “Doctor, it hurts when I do this.”

Mitch: “Well, don’t do that.”