I am using Ansible to push configuration. I have a task inside a playbook that I want to start an ssh tunnel in the background for MongoDB. The task command that i'm using is

- name: Start tunnel service
  shell: ssh -f -N -L 27018:localhost:27017 mongo@remote-server 

But no matter what I do I cannot get ansible to continue. Instead it hangs or acts like it is waiting on something to return a response. If I run this command in the shell like normal it doesn't have any problems and I can connect to the remote mongo instance.

At first I thought because I was setting up a new server that ssh's known_hosts were waiting for a user to respond yes/no before moving on. In this case I tried two options. First I tried adding the server's fingerprint to the known_hosts file. After running from the shell it didn't asked for a known_hosts entry, but ansible also is still hanging. I also tried the option of

ssh -o StrictHostKeyChecking=no -f -N -L 27018:localhost:27017 mongo@remote-server

But this option is also producing the same problem with ansible hanging.

I have tried switching between ansible's command and shell module without any change to the problem. My most recent experiment was to try nohup before the command, but this isn't working either.

nohup ssh -f -N -L 27018:localhost:27017 mongo@remote-server

Also trying to get creative thinking that if a different process was able to run the command that afterwards it would send a response back to ansible, I tried wrapping it as an Upstart task. I placed the shell command inside a /etc/tunnel.sh file and also put the upstart script in /etc/init/tunnel.conf. But this also doesn't work and seems to have trouble actually starting the script. If I run sudo service tunnel start it will start but has trouble stopping. Though running this through ansible as a command doesn't do anything and just sits there and hangs like all the other experiments.

- name: Start tunnel service
  command service tunnel start
  • If you want the tunnel to be running all the time, you should use upstart. Can you paste your upstart script? – dbanck Sep 23 '13 at 16:01
  • I will paste the upstart script, but after getting it to run on the server mongo has trouble using it to connect. I know the upstart script is running when I start/stop it because I can go into logs/upstart and see the error message for trying to bind to the same port multiple times. I actually have solved this problem by implementing autossh and I believe this would be the recommended way. Next I am going to use upstart to control autossh tunnel. – lumberjacked Sep 23 '13 at 20:04

If you're using sudo and a key I would wager you're not preserving the SSH_AUTH_SOCK environment variable. This will be required in order to establish a connection from the orchestrated machine to the mongodb instance. In this situation you should add something like the following to /etc/sudoers:

Defaults        env_keep+=SSH_AUTH_SOCK
Defaults        env_reset

I did the same test and found it is because ssh command ask for fingerprint confirmation when you first time ssh, therefore ansible stuck and couldn't handle remote prompt.

The easy way could be tweak you ssh tunnel command as below:

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -f -N -L 27018:localhost:27017 mongo@remote-server 

it will bypass the hostkey checking and put your ansible task thru.


You can also use the async actions of ansible (http://docs.ansible.com/playbooks_async.html)

- name: Start tunnel service
  shell: ssh -f -N -L 27018:localhost:27017 mongo@remote-server
  async: 15
  poll: 5

This will allow ansible to complete the task giving it 15 sec max run time to execute and poll every 5 sec for a completion.


Instead of nohup, why not try using screen instead?

ssh user@server screen -dR command

screen is a lot nicer because you can just detach the session with CTRL-A,D, then log out, and when you need to come back to the session later just log into the server with ssh and hit CTRL-A,1 or just keep hitting CTRL-A until it loads the session.

  • Screen is not working either. Thank you for the suggestion, but I think I need to find the solution the ansible way. It is obvious ansible is waiting for something to happen. – lumberjacked Sep 22 '13 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.