Using TFS Build Agents to your advantage

As you may already know, TFS includes a very powerful build system called Team Build.  Having looked at a few different build systems in the past, I have yet to see one with as much power and flexibility as Team Build.  This being its third iterations (2005, 2008, and now 2010), it has grown a lot since it first came out.  A lot of its basic functionality, such as MSBuild integration, has not changed at all, but its moving pieces and configuration have changed drastically. 

Today we are going to take a look at Build Agents and Build Controller.  Not much changed in the way that builds were executed through agents between TFS 2005 and 2008.  TFS 2010 introduced the concept of Build Controllers, which are responsible for managing one or more Build Agents in order to work through a build queue.  This illustration from MSDN describes the relationship between a Team Project Collection, a Build Controller, and a Build Agent:

IC292936[1]
Source: http://msdn.microsoft.com/en-us/library/dd793166.aspx

The way it works is that a build controller is assigned to a Team Project Collection.  If a new Team Project Collection is added to TFS, that collection, you would assign one or more controllers to it, but you cannot assign a controller to more than one collection.  The build controller can live on any machine, but it’s always a best practice to keep it on a separate machine than the TFS Server.  The Build Controller processes the defined workflow and then hands off the “heavy” work to the build agents, but the only one that communicates directly with TFS is the build controller.  You can have as many build agents assigned to a build controller (across as many machines as you’d like) and each build agent can only be assigned to one controller (again, no sharing).

Ok, so now that you know all you ever need to know about controllers and agents, what is the best way to take advantage of this architecture? 

Use a specific agent for a build definition
When you define a build, you can find the “Agent Settings” section under “Advanced”.  Under that section, you can specify which agent should run a build for that definition.  The property is “Name Filter” and it has an asterisk by default, which means that any available agent should be used, you can change that to any of the agents on the drop-down list”.   This will ensure that only the selected agent will get picked for that build.  I’m not a huge fan of that setting since it can create a bottleneck, but it’s good to use in environments when only a specific agent has been setup to take care of a specialized activity.
image

Use Tags to determine which agent to use
Each build agent can be tagged with any combinations of keywords that make sense in your environment.  These tags can be used by the controller when deciding what agent a specific build should be sent to.  To get to the agent properties, you right-click on the “Builds” item in Team Explorer and select “Manage Build Controller”, select your agent and select “properties”.  On that screen you can add any tag that you’d like.
image
In the sample above, I’ve selected the tags “Silverlight” and “x86” for my agent “Test”.  These tags don’t have any logic behind them, they are just metadata and I can choose any meaning for them.  In this specific scenario, it means that my agent has all the required bits to be able to compile a Silverlight application and that it is running on an 32-bit build machine.  Looking at the previous image, we can see that we have 2 properties on our build definition that relate to this:
– Tag Comparison Operator: Can be set to “MatchExactly” or “MatchAtLeast”
– Tag Filter: List of Tags that should be used when finding an agent
These two properties work together to figure out which agent to use.  This can be a very powerful way to balance the load between all my agents in order to not create a bottleneck and at the same time make sure that the right software is installed on the machine hosting the agent in order to guarantee a good build.

Build in Parallel
If your build requires that you build across multiple platforms (x86/x64) or configurations (Release/Debug), you can parallelize your build and take advantage of idle build agents.  There’s a great post on it here: http://blogs.msdn.com/b/jimlamb/archive/2010/09/14/parallelized-builds-with-tfs2010.aspx

Now that you have these tools available in TFS 2010, use them to your advantage to speed up your builds or make them a lot more powerful than they were before.  As you outgrow your current agent setup, re-think your configuration and add/remove hardware as needed.  Make use of virtualization as much as you can, as these agents should be easy to swap in and out of rotation.

About esteban

Esteban is the Founder and Chief Technologist at Nebbia Technology, an ALM consulting and Azure-powered technology company. He is a software developer with a passion for ALM, TFS, Azure, and software development best practices. Esteban is a Microsoft Visual Studio ALM MVP and ALM Ranger, Pluralsight author, and the president of ONETUG (Orlando .NET User Group).

2 thoughts on “I’m on Radio TFS # 103!

  1. Renato Bento

    Thank you,
    this really helped me out!
    I was on a hard path trying to parse this parameters as a XmlDoc.

  2. Jorge Sanchez

    Hey I being using your code to accomplish the same thing but I never work with TFS before, I think I got it to the part that I could pass the ProjectFilePath and NewAssemblyName, but I not sure how to pass the Workspace InArgument do you have an example of how do I specify this on MsBuild?

    BTW i also change

    var workspace = context.GetValue(this.Workspace);
    to
    var workspace = (Workspace)context.GetValue(Workspace);

    is this correct?

    Thank you very much


Leave a Reply

Your email address will not be published. Required fields are marked *

Are you human? *