TFS2015 Release Management: Deploying to an untrusted domain

I’ll show how to configure TFS2015 Release Management to be able to deploy to another (untrusted) domain by having the deployment agent run under a shadow account.

Introduction

The Release Management functionality in TFS2015 update 2 allows for automated deployment of software in one or more environments. The idea is that you configure a deployment agent in every environment that you want to deploy to (such as test, user acceptance or production) and register it with your TFS server so that it will listen for new releases to be deployed to that environment.

While definitely a big improvement over the VS2013 Release Management product, the downside to the deployment agent is that it needs to run under the same account as the account used to communicate with TFS with. This poses a problem when the environments to deploy to live in different domains from the TFS server (without trusts): you can’t run the agent as a TFS user because it doesn’t exist in the target environment. Conversely, if you run the agent as a user from the target environment there’s no way to grant that user permissions within TFS.

Until Microsoft provides a way to specify an extra set of credentials for this, we’ll have to resort to using a shadow account: By creating a local user in the target environment that has the same login and password as the TFS user, Windows will treat both as the same user.
Even then it requires a bit of trickery though, which is what I’m going to show next.

Our setup

For the purposes of this post, I have a TFS2015 Server with update 2 at https://mytfs2015/tfs, which is located in my development domain called DevEnv. I want to install an agent on the WebSrv machine inside the domain TestEnv. The DevEnv and TestEnv domains don’t trust eachother, but the https://mytfs2015/tfs url must be accessible from the WebSrv machine without a firewall intervening.

In TFS, I have an Agent Pool (configurable via Control Panel, Agent Pools), and my own account is part of its Agent Pool Administrators role. I have created a user DevEnv\svcTstDeploymentAgnt and made him member of the Agent Pool Service Accounts role; this will be the user under which the agent will run.

Creating the shadow account

  • Sign in to the TestEnv\WebSrv machine using any administrator account and use Computer Management to create a local user named svcTstDeploymentAgnt. Give it the same password as the DevEnv\svcTstDeploymentAgnt user, so that it can be used as a shadow account.
  • For the duration of this installation, WebSrv\svcTstDeploymentAgnt needs administrator permissions, so add it to the local Administrators group.

Installing the agent – part 1

  • Now, sign in to the WebSrv machine using the WebSrv\svcTstDeploymentAgnt we just created.
  • Open up https://mytfs2015/tfs (using your regular user account) and download the agent (via Control Panel, Agent Pools).
  • Extract the agent.zip, e.g. to C:TfsDataAgentsAgent-WebSrv
  • Open an elevated command prompt, navigate to C:TfsDataAgentsAgent-WebSrv and run ConfigureAgent.cmd.
  • Specify the Name, TFS URL and agent path as requested, and choose to install the agent as a windows service
  • For “the name of the user account to use for the service”, specify svcTstDeploymentAgnt, followed by its password
  • Next, the installer will try to connect to the TFS instance and should ask you for your credentials (if not, there are already cached credentials which should first be cleared via the Windows Credential Manager, see below). Specify your own user account.

The installer will run, but will terminate with an error:

1
2
3
4
5
Installing service vsoagent.tfs.Agent-WebSrv...
Service vsoagent.tfs.Agent-WebSrv has been successfully installed.
Creating EventLog source vsoagent.tfs.Agent-WebSrv in log Application...
TF14045: The identity with type 'System.Security.Principal.WindowsIdentity' and identifier
    'S-1-5-21-2986214872-1000940727-4115246995-1004' could not be found.

Also, the agent will be listed in red under the Agents pool:

At this point the agent is registered succesfully with TFS, but refuses to run. This can also be seen in the logfile (inside the agent’s _diag folder), which should contain:

1
2
3
08:47:34.856145 Authenticating to the server https://mytfs2015/tfs
08:47:35.043644 Failed to create session. Sleeping for 10 seconds before next retry.
                Attempts=1/10.

Installing the agent – part 2

To fix this, we need to reinstall the agent, this time using the DevEnv\svcTstDeploymentAgnt to authenticate with to TFS.

  • Go to the windows credential manager and remove the Windows credentials for your own account (that you used to sign in with to TFS), so that the installer will ask for your credentials again.
  • Now run ConfigureAgent.cmd again, and specify the same values as before for the Name, TFS URL, Agent path and Windows Service credentials.
  • This time, specify the DevEnv\svcTstDeploymentAgnt credentials when connecting to TFS.

Again the installer will end in an error:?

1
2
Access denied. svcTSTDeploymentAgnt needs Manage permissions for pool MyAgentPool to perform
the action. For more information, contact the Team Foundation Server administrator.

However, the agent should now be listed as green in the Agent Pool overview (you might need to refresh the page) and running correctly.

Also, the logfile in the _diag folder should report something like:

1
2
3
4
5
09:01:27.158926 Authenticating to the server https://mytfs2015/tfs
09:01:27.346417 Created Session: 83b37942-d0be-44b0-85a0-00ae147271cc
09:01:27.362042 MessageQueueListener.DispatchAsync - starting loop
09:01:27.362042 MessageQueueListener.DispatchAsync - Getting message from Session:
                83b37942-d0be-44b0-85a0-00ae147271cc

Despite the last error message, the Agent is now ready to receive deployments.

Conclusion

As you can see from the steps involved and the number of error messages, this isn’t the most elegant solution, but hey, at least it works… Cheers!