Visualise and create build chains in TeamCity, the easy way
We all like nicely organised and efficient deployment pipelines (at least the really OCD among us do :). There are the simple cases where you have a sequential line of steps like so:

With every commit you want to trigger step 1 and if it finishes successfully, step 2 and 3, until the end. It is easy enough to implement that in TeamCity. We add a VCS root and a VCS commit trigger on step 1, then a finish build trigger in each of the next steps for when the previous one finished successfully. Git triggers 1, 1 triggers 2 and so forth until we reach the end of the pipeline. But what about when your pipeline looks like this:

Here we want to run in parallel some things because we have more than one agent and we will save up much time doing so. “Finish build” triggers don’t cut it anymore though because we do not want to run 3 until both 2.1 and 2.2 have finished successfully. Same for 5 down the line.
The solution to this is the notion of snapshot dependencies in TeamCity. When we set them up properly we get to see some nice graphs in the Project view, Build chains tab:

The only problem is that for relatively complex pipelines, figuring out what dependencies to add to what build configuration can be tricky. There is no nice visual editor in TeamCity to help you with the design of the pipeline either. Don’t you wish you could create a nice flowchart of your build configurations and it would just work? Well, you can’t. But this is where this article comes in. The trick is simple:
Visualise the pipeline and work backwards
Simply jot down the pipeline as you want it to be and go straight to the last step. In our “complex” pipeline above, 5 is the one that will get the VCS trigger. Remember when setting this trigger to check the box “Trigger a build on changes in snapshot dependencies” in order to get your whole build chain going when something gets committed to your repository.
Now look at the arrows that go into it, to its left. These are the snapshot dependencies you need to set on 5, in this case 4.1 and 4.2. The “Do not run new build if there is a suitable one” checkbox will be checked in our case because we do not need to trigger the successful steps up the chain if there have run successfully. Alternatively you can have it unchecked and re-run the whole chain whether there are suitable builds or not (in our case triggering the pipeline manually qualifies as “suitable” and will basically skip all steps, you’ll have to run the steps you want executed again manually). At the “On failed dependency” select box we will make the build failed to start because we do not want the pipeline to continue if the previous step fails (this setting could be set to “Run build, do not add problem” if it is something that can be skipped if it fails, like notifications).
And now just rinse and repeat! In the case of 4.1 and 4.2 there is only one snapshot dependency for each, step number 3. For 3 it’s 2.1 and 2.2 aaand you get the point… At the end, step 1 is the one with the VCS root attached to it and no triggers or dependencies. As a matter of fact there are no triggers anywhere in the pipeline apart from the VCS trigger on the last step.
Take note that you might need to pass around artifact dependencies as usual, depending on what your steps actually do.
As an extra bonus you’ll see that the diagram you drew to make this all happen is the exact same as the one drawn by TeamCity in the Build chains tab:

This technique would be especially handy if you’re unfortunate enough to have a pipeline that looks like this:

Again, just start from 6 and work your way backwards. To be fair, you should try to simplify it first though. Simplicity and Readability do not apply only to code. Spare a thought for the poor dev/admin that will come after you and will have to maintain the pipeline…
And that’s it! I hope I took some effort out of some dev’s and admin’s day. As always, let the community know what you think and what alternative solutions you might have put in place. Happy coding :)
I just happened to come by this blog post (that I only found a month after I did the work :) deep in the TeamCity documentation that describes exactly what I wrote above, along with other very useful information. You should read it here.