Using SSH in TeamCity

Published on Wednesday 6 December 2017

For a product I worked on we needed to extract data from a Software as a Service (SaaS) SAP installation as part of our TeamCity build jobs in Azure, but we only had access to the SAP system from within our own network because of the SaaS provider's white list policy. Adding our Azure build agents to the white list was not an option as build agents were created as needed and disposed after a given period of inactivity.

That TeamCity agents were created as needed also limits the ability to configure SSH for the user running the actual TeamCity build process as this configuration would be wiped for each new agent because of sysprep.

However we had the possibility of opening a SSH tunnel with local port forwarding to a machine within our network and thus access the SAP installation.

So for better or for worse that is what we decided to do. This post describes the solution and the process of arriving at that solution plus identifying a few shortcomings.

What we did:

However the main problem with this approach was that the TeamCity SSH Agent keeps the tunnel open as long as the TeamCity agent is active. So a way to close the tunnel again was needed.

So we used the SSH config file to get access to the ControlMaster feature.

Host <DNS entry>
BatchMode yes
ControlMaster auto
ControlPath ~/.ssh/ssh-%u-%i-%r@%h-%p
ExitOnForwardFailure yes
LocalForward <local port> <remote IP>:<remote port>
StrictHostKeyChecking no
User <Username for SSH tunnel>

By using the control master it is possible to open the connection at the beginning of the build job:

ssh -F "./ssh/config" -fn -M -N -T <DNS entry>

and at the end of a build job simply shutdown the connection:

ssh -F "./ssh/config" -T -O "exit" -o "LogLevel=ERROR" <DNS entry>

See the SSH Manpage for explanations of the different switches used.