One reason to upgrade to TFS 2017: Code search

I always suggest teams to use VSTS instead of on-premise TFS. The main reason is avoiding any issue with administration or upgrades. In these years, one of the main risk of having TFS on-premise is not planning for upgrade and keeping the first version installed for years. As a result, it is not uncommon to have teams that still uses TFS 2013 even if version 2017 is out.

For small teams usually there is not a dedicated TFS administrator; in this situation is it strongly advisable not to skip one entire major upgrade, to minimize the risk of a big bang upgrade. Suppose you have TFS 2015, I strongly suggest you to upgrade to TFS 2017, before another major version is out. This will prevent to have to upgrade 2 or more major version, with the risk of long upgrade times and too many changed that could makes the user upset.

As a general rule, if you need to use on-premise TFS, you should upgrade as frequently as possible and never skip one major upgrade.

If you are not sure that upgrading to TFS 2017 worths the time needed to plan an perform the upgrade, I’d like to share with you some of the new exciting new features.

My favorite feature of TFS 2017 is Code Search, that allows to perform semantic searches within code.

Every developer loves experimenting new libraries, new patterns etc, and in the long run Hard Disks of people in the team is full of small little projects. One day you remember that someone wrote a Proof of concepts to test bulk load with ElasticSearch but you do not know how to find the code. The obvious solution is storing everything inside your TFS (VSTS), using Git or TFVC, then search code with this new exciting functionality.

In TFS 2017 you have the “Search code” textbox, in the left upper part of the Web UI, and if you start typing a nice help allows you to view the syntax you can use.

clip_image001

Figure 1: All the syntax used to search inside code with the new Search Code Functionality

As you can see you can search text inside name of a class, comment, constructor, etc, and you can also use AND OR NOT. This gives you a tremendous flexibility and usually in few seconds you can can find the code you need. Results are presented in a nice way, and you can immediately jump to the code to verify if the result is really what you are searching for.

clip_image002

Figure 2: Results allows you to immediately browse the file with the match within the Web Ui

If you still are in TFS 2015 or earlier version, I strongly suggest you to plan for an upgrade to 2017, to use this new exciting feature.

Gian Maria.

Scale out deployment error when migrating Reporting Services

Part of moving your TFS Server on new hardware, or creating a Pre-Production environment is restoring Reporting Server database. Since Datatbase are encrypted, if you simply restore the database then configure Reporting Services on new machine to use restored database, this operation will fail, because the new server cannot read encrypted data.

Restoring Reporting Services database into a new instance involves some manual steps, especially you need to backup / restore encryption keys from your old server to the new one.

Clearly you should have a backup of your encryption key, this is a part of a good backup process, and it is automatically performed by the standard TFS Backup wizard. If you never backupped your encryption key I strongly suggest to DO IT NOW. The backup procedure can be done manually from Sql Server Reporting Service Configuration Manager.

image

Figure 1: Backup your encryption key

You should choose a strong password and then you can save the key in a simple file that can be moved and imported on the machine where you restored your Reporting Services database. On that server you can simple use the Restore feature to restore the encryption key so the new installation is now able to read encrypted data from database.

If the name of the machine is changed, as an example if you perform a restore on a Test Environment, when you try to access your reporting server instance you probably will got this error

The feature: “Scale-out deployment” is not supported in this edition of Reporting Services. (rsOperationNotSupported)

This happens because the key you restored belongs to the old server, and now your Reporting Server instance believe that it is part of a multi server deployment, that is not supported in standard edition of Reporting Services.

image

Figure 2: Scale out Deployment settings after key is imported.

In Figure 2 you can verify that, after importing the encryption key, I have two server listed, RMTEST is the name of the machine where I restored the DB while TFS2013PREVIEWO is the name of the machine where Reporting Service was installed. In this specific scenario I’m doing a clone of my TFS Environment in a Test Sandbox.

Luckly enough there is this post that explain the problem and gives you a solution. I must admit that I dot feel really confortable in manually manipulation of Reporting service database, but the solution always worked for me. As an Example, in Figure 3 you can see that I have two entries in the Keys table of reporting database

image

Figure 3: Keys table contains both entries for keys.

After removing the key of TFS2013PREVIEWO from the database the Scale Out settings come back to normal, and reporting services starts working.

image

Figure 4: Reporting services are now operational again.

Gian Maria.

Isolate your TFS Pre-Production environment for maximum security

In previous post I’ve explained how to create a clone of your TFS Production environment thanks to the new TFS “15” wizard. With this post I want to share you a simple solution I have in my Bags of Tricks to avoid your TFS Cloned environment to interfere with production environment.

The problem

In my environment I have all machines in network 10.0.0.0/24, my TFS has address 10.0.0.116 and Primary Domain Controller is 10.0.0.42. Then I have automated build and Release Management Definitions that deploy against various machines, : 10.0.0.180, 10.0.0.181, 10.0.0.182, etc.

Even if I used the wizard, or Command Line instructions to change TFS Servers id, there is always the risk that, if a build starts from cloned environment, something wrong will be deployed to machines used by production environment (10.0.0.180, etc).

Usually the trick of changing hosts files in PreProduction TFS machines is good if you always use machine names in your build definition, but if I have a build that directly deploy to 10.0.0.180 there is nothing to do. This exposes me at risk of production environment corruption and limits my freedom to freely use cloned TFS environment.

What I want is complete freedom to work with cloned TFS Environment without ANY risk of accessing production machines from any machine of Cloned Enviroments (Build controllers, test agents, etc).

Virtualization to the rescue

Instead of placing pre-production environment in my 10.0.0.0/24 network, I use Hyper-V virtual networking capabilities to create an internal network.

image

Figure 1: Virtual networks configured in Hyper-V hosts

In Figure 1 I depicted what I have clicking the Virtual Switch Manager setting (1), and I have a virtual switch called “Internal Network” (2) that is configured as internal network (3). This means that this network can be used by all VM to communicate between them and with the host, but there is no possibility to communicate to the real Production Network. The Physical network card of Hyper-V host is bound to a standard “External Network”, it is called “ReteCablata” (4) and it is the network that can access machines in Production Network.

With this configuration I decided to install all machines that will be used for TFS Pre Production (server, build, etc) using only the “Internal Network”. The machine I’ll use as Pre Production TFS has the address 10.1.0.2, while the Hyper-V host will have the 10.1.0.254 address. This allows for my Hyper-V hosts to communicate with the Virtual Machine through the Internal Network virtual network interface.

Now if I try to login to the machine with domain credentials I’ve got a bad error as result.

image

Figure 2: I’m unable to login with domain users, because domain controller is unavailable.

Accessing with local user is good, and the reason why I cannot login as domain user is because the machine is not able to reach the domain controller, since it lives in another virtual network.

Thanks to this solution I’ve created an isolated subnetwork where I can create my TFS Pre-production / Test environment without the risk of corrupting the Production Environment

Thanks to Virtual Networking it is easy to create a virtual network completely isolated from your production environment where you can safely test cloned environment

Iptables to route only what-you-want

At this point I have an isolated environment, but since it cannot access my domain controller, I have two problems:

1) PreProduction / Test Tfs cannot access the domain, and no domain users can access TFS
2) To access the PreProduction / Test TFS you can only use the Hyper-V host.

Clearly this made this approach almost impraticable, but the solution to this limitation is really really quick. Just install a Linux machine in the Hyper-V host to act as a router, in my example I have a standard Ubuntu Cloud server without UI. The important aspect is that you need to assign both Virtual Networks to the machine, so it can connect with both your isolated environment “Internal Network” and production environment “Rete Cablata”.

image

Figure 3: Create a Linux VM and be sure to assign both network interfaces.

In my box the physical network (ReteCablata) is eth0 while the internal network is eth1, both interface have static ip, and this is the configuration.

gianmaria@linuxtest1:~$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
     address 10.0.0.182
     netmask 255.255.255.0
     gateway 10.0.0.254
     dns-nameservers 10.0.0.42

auto eth1
   # iface eth1 inet dhcp
   iface eth1 inet static
   address 10.1.0.1
   netmask 255.255.255.0
   network 10.1.0.0

The configuration is simple, this machine has 10.0.0.182 ip in my production network (eth0), and it the 10.1.0.1 ip in the internal virtual network (eth1). Now I configured all Windows machines in the internal virtual network to use this machine as gateway.

image

Figure 4: Configuration for Pre-Production TFS Machine

The important aspect is that it is using the ip in eth1 of linux machine as gateway (10.1.0.1), and it is using 10.0.0.42 as DNS (this is the address of my primary domain controller).

Now I can configure the linux box to become a router between the two networks, you should enable forwarding as first step with the instruction

echo 1 > /proc/sys/net/ipv4/ip_forward

But this works only until you reboot the linux machine, if you want the configuration to survive a reboot you can edit /etc/sysctl.conf and change the line that says net.ipv4.ip_forward = 0 to net.ipv4.ip_forward = 1. When forwarding is enabled, you can configure iptables to route. Here is the configuration:

Disclaimer: I’m not absolutely a linux expert, this is a simple configuration I’ve done after studying a little how iptables works and thanks to articles around the web.

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o eth1 -m state  --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -I FORWARD -d 10.0.0.0/24 -j DROP
sudo iptables -I FORWARD -d 10.0.0.42 -j ACCEPT

The first three instructions are standard rules to configure iptables to act as a router for ALL Traffic between eth0 and eth1 and vice-versa. With only the first three rules all the machines in 10.1.0.0/24 network that uses 10.1.0.1 (the linux box) as gateway can access internet as well as ALL machine in network 10.0.0.0/24 (Production Network). This is not enough for me, because with this configuration machine in Cloned TFS Environment has FULL access to production machines.

The fourth rule tells to iptables to DROP all traffic from any direction to subnet 10.0.0.0/24. This rule will completely isolates the two network, no machine can access the 10.1.0.0/24 from 10.0.0.0/24 and vice versa. Then the fifth and last rules tells iptables to ACCEPT all traffic from and to the address 10.0.0.42, my domain controller.

Thanks to iptables and a Linux box, it is really easy to create a router that selectively filter access from the two networks. This gives you the freedom to decide what machine of production environment can be accessed by cloned environment.

With this configuration I have created an isolated network that is capable of contacting ONLY my domain controller 10.0.0.42 but otherwise is COMPLETELY isolated from my production network. This allows PreProduction / Test TFS machine to join the domain and validate users, but you can safely launch build or whatever you want in any machine of the Cloned environment because all traffic to production machine, except the domain controller, is completely dropped.

How can I access PreProduction environment from client machine

Previous configuration solves only one of my two problems, PreProduction TFS can now access only selected machine of the domain (Domain Controller usually is enough) but how can you let Developers or Manager to access PreProduction environment to test cloned instance? Suppose a developer is using the 10.0.0.1 machine in production network, and he want to access PreProduction TFS at 10.1.0.2 address, how can you have it access without forcing him to connect to Hyper-V host and then use the Hyper-V console?

First of all you need to tell iptables to allow traffic between that specific ip and the isolated virtual network in eth1.

sudo iptables -I FORWARD -d 10.0.0.1 -j ACCEPT

This rules allow traffic with client ip so packets can flow from 10.0.0.1 to every machine in 10.1.0.0/24 network. This is necessary because we tell iptables to DROP every traffic to 10.0.0.0/24 except 10.0.0.42, so you need this rule to allow traffic to client Developer machine. All other machine in production network are still isolated.

Now the developer in 10.1.0.0 still can’t reach the 10.1.0.0 machine because it is in another subnet. To allow this he simply need to add a route rule in his machine. Supposing that the 10.0.0.1 machine is a standard Windows machine, here is the command line the developer need to access Cloned Environment Machines.

route ADD 10.1.0.0 MASK 255.255.255.0 10.0.0.182

Thanks to this roule the developer is telling to the system that all traffic to 10.1.0.0/24 subnet should be routed to 10.0.0.182, the address of the Ubuntu Linux machine in production environment. Now when developer try to RDP the 10.1.0.2 machine (Cloned TFS Server) all traffic is routed by the linux machine.

Final Consideration

Thanks to this configuration all machines in the 10.1.0.0/24 network, can contact and be contacted only by selected production machines, avoiding unwanted corruption of your production environment.

This gives you complete contorol on the IP addresses that can access your Cloned environment, reducing the risk of Production Environment corruption to almost zero. You can allow access to selected machine, and also you can control which client machine in your production network can access Cloned Environment.

Remember that, after a reboot, all rules in iptables will be cleared and you need to setup them again. You can configure Linux box to reload all rules upon reboot, but for this kind of environment, I prefer to have the ability to reboot Linux machine to completely reset iptables. Re-applying rules is a matter of couple of seconds.

Gian Maria.

Create a Pre-Production / Test environment for your TFS

There are a lot of legitmate reasons to create a clone of your TFS installation: verifying an upgrade, testing some customization and so on, but traditionally creating a test environment is not an easy task.

The problem is avoiding that the test installation could interfere and corrupt your production instance and since TFS is a complex product, there are a series of steps you need to do to perform this kind of operations. Thankfully with the upcoming version of TFS most of the work will be accomplished with a wizard.

Kudo to TFS Team for including a wizard experience to create a clone of your TFS Environment.

Here are the detailed steps to create a clone environment.

Step 1: Backup Database / install TFS on new Server / Restore Database

First of all you can login to your TFS server, open c:\Program Files\Microsoft Team Foundation Server 14.0\Tools and launch TfsBackup.exe to take a backup of all databases.

2016-07-09_11-16-26

Figure 1: Take a backup of your Production Database

You should only specify the name of the instance of SQL Server where you have your production databases. A wizard will start asking you to select databases to backup and the location where you want to place the backup.

2016-07-09_11-17-23

Figure 2: Choose databases to backup

The backup routine will perform a full backup.

2016-07-09_11-22-06

Figure 3: Backup is taken automatically from the routine

Next step is creating a new Virtual Machine, install Sql Server in a compatible version with TFS “15” preview (I suggest SQL 2016) then install TFS.

2016-07-09_12-20-57

Figure 4: Install TFS on the target machine

Once the installer finishes TFS “15” Configuration wizard will appear

2016-07-09_12-31-08

Figure 5: Once installer is complete the Configuration Wizard will ask you to configure the server

Now you should go to c:\Program Files\Microsoft Team Foundation Server 15.0\Tools and launch TfsRestore.Exe.

2016-07-09_12-31-42

Figure 6: TfsRestore will perform database restore

You should only choose the name of the SQL Server instance you want to use, in this example I’m creating a Pre-Production environment composed by only one machine called RMTEST. You should transfer backup file to target computer or place them in a network share accessible from the Target machine.

2016-07-09_12-33-53

Figure 7: Restore routine will prompt you for Backup Location

Once you specify the directory with the backup the wizard will automatically list all the database to restore for you.

2016-07-09_12-36-00

Figure 8: Database are restored in Sql Server

Step 2: Extra security precautions to avoid Production corruption

Now all databases are restored in the Sql Server that will be used by the Pre-Production environment and you can start TFS configuration wizard, but I’ll wait to perform extra security precautions.

You should edit the hosts file of Pre-Production machine to redirect to an inexistent IP every machine name used in Production Environment. As an example, I have Build and Release definition that will deploy software on demo machines, and I want to prevent that a build triggered on Pre-Production TFS Instance will access Production servers.

As extra security tip, I suggest you to use the hosts file trick to minimize the risk of Production Environment corruption

image

Figure 9: Editing hosts file will guarantee extra safety net against Production environment corruption

As an example, in Figure 9 I showed a typical hosts file, the Production instance is called TFS2013PreviewOneBox so I redirect this name to localhost in the new name. Then I redirect all machines used as deploy target or build server etc to 10.200.200.200 that is an unexistent IP.

You can also create some network rules to isolate the Pre-Production machine from the Production Environment completely, such as placing it in another network segment and prevent routing entirely, but using the hosts file is a simpler approach that works well for small and medium installation.

Step 3: Perform the configuration with new TFS “15” wizard

Before TFS “15” now you should resort to command line trickery to change server id from database etc, but luckily you can do everything using configuration wizard. Lets come back to Configuration Wizard and choose the option “I have existing database to use … “

2016-07-09_12-36-22

Figure 10: Start upgrade wizard using existing databases

The wizard will prompt you to choose the instance of Sql Server and the database to use.

2016-07-09_12-36-44

Figure 11: Choose database to use for the upgrade

Until now it is the standard Upgrade Wizard, but the next screen is the great news of this new installer because it will present you the option to create a Pre-Production environment.

2016-07-09_12-42-20

Figure 12: This is the new option, you can choose to create a Pre-Production Upgrade Testing

Pressing Next you will see another screen that reminds you the step that the wizard will perform to create the Clone environment. As you can see the wizard will take care of remapping connection string, changing all identifiers and remove all scheduled backup jobs.

2016-07-09_12-42-37

Figure 13: Overview of the Pre-Production scenario

Thanks to the wizard you can create a Test Clone of your Production TFS without worrying to corrupt your Production environment. The wizard will takes care of everything

Now the wizard will continue, but there is another good surprise, each screen contains suggestions to minimize risk of Production Environment corruption.

2016-07-09_12-44-40

Figure 14: Wizard suggests you to use a different user to run TFS Services

The suggestion in Figure 14 is the most important one, I usually use an account called TfsService to run my TFS Server and that account has several privileges in my network. In the Pre-Production environment it is better to use standard Network Service account or a different account. This is a really important security settings, because if the Pre-Production server will try to perform some operations on other servers it will probably be blocked because the account has no right permission.

Never use for Pre-Production environment the same users that you use for Production environment to minimize risk of corruption. Use Network Service or users with no privilege in the network created specifically for Cloned Environments

Clearly the wizard will suggest you to use different url than production server. Resist the temptation to use the same url and rely on hosts file redirection, it is really better to use a new name. This will allows you to communicate this new name to the team and ask them to access Pre-Production server to verify that everything is working, as an example after a test upgrade.

2016-07-09_12-45-02

Figure 15: Use a different url than production environment

You can now follow the wizard, basically the screen are the same of the upgrade, but each screen will suggest you to use different accounts and different resources than production instance.

At the end of the wizard you will have a perfect clone of your production environment to play with.

2016-07-09_12-56-10

Figure 16: Configuration is finished, you have now a Clone of your environment.

Step 4: extra steps for furter extra security

If you want to be Extra sure that your production environment is safe from corruption, configure the firewall of your Production system to block any access from IP of any machine part of cloned environment. This extra security measure will prevent human errors.

Some customers have custom software that connect to TFS instance to perform some custom logic. As an example you could have software that use bisubsribe.exe or hooks to listen to TFS events then send command to TFS. Suppose you want to test this kind of software against your Cloned environment, so you let people install and configure everything on Pre-Production machine, but someone did a bad mistake and configured the software to listen to the Pre-Production environment, but send command against Production Environment. If you blocked all traffic from Pre-Production machines to your TFS Production environment you will be protected against this kind of mistake.

If you are good in networking, probably the best solution is creating all machines part of Pre-Production environment (TFS, SQL, build server, etc) in another network segment, than configure routing / firewall to allow machines in pre-prod network to access only domain controllers or in general to access only machine that are stricly needed. This will prevent machines from Pre-Production environment to connect any machine of your Production Environment. You can then allow selected ip from your regular network to access Pre-Production for testing.

Gian Maria

TFS 2015 Update 2 is released

You can find all the details directly in Visual Studio Site, but I want to emphasize that TFS and VS Updates are much more than Service Packs, because they also intrdoduce a lot of new features. Here is a list of my personal favorites features of TFS Update 2

Introduction of new Release Management System

New release management system is completely Web and does not require separate client to download, but this is not the only advantage. This update introduces the ability to integrate with VMWare, and have a new extension to connect to System Center Virtual Machine Manager.

Delete of work item from the UI

This solves probably the most common question I got during TFS Courses. Basically every attendee asks “how can I delete Work Item?”. The usual answer is, you need to resort to Command Line utility, because deleting a Work Item actually deletes its history from database and its a dangerous operation to do.

This is not always true, there are lots of legitimate reasons to delete a Work Item and now it is possible to delete Work Items directly from the Web Interface. Deletion actually move Work Items to a Recycle Bin where you could still restore deleted Work Items or delete permanently.

Extension from marketplace

This is another really cool feature, Marketplace was available until now, only for VSTS accounts, but now you can add extensions even to your TFS on premise instance.

Gated Check-in for new build system

This was another great stopper for customer to adopt the new build system, until Update 2 the new build system has no support for Gated Check-in. With Update 2 you can create a Gated Check-in TFVC vNext build

New Link from Git Code and Work Items

Now you can link a work item not only to a Commit in Git but also to an entire branch. This is really interesting if you work with GitFlow and are used to feature branches. With this approach you can link each PBI or User Story directly to Git Feature branch that is implementing it.

This is especially useful for Scrum Team, because you can create a pull-request for all Completed User Stories of the Sprint, and do a review. Then, during Sprint Review, you can complete pull requests only for those User Stories that are considered completed by the Product Owner. All the User Stories that are still not considered completed will flow to the Next Sprint, postponing the Merge.

I strongly encourage you to have a look at the full list of the new feature, and, as always, I strongly suggest you to always upgrade your TFS to the latest version, to have all the latest bugfix and to avoid Big Bang upgrade that spans multiple versione (ex 2008 to 2013, or 2010 to 2015).

Gian Maria.