As an additional datapoint, here's a brief summary of how I deal with this. To complicate matters, my machines are split across various labs in different locations which each have their own bastion/jumpbox. I use ssh keys sometimes, and hard coded passwords for some other machines:
ansible.cfg: [defaults] hostfile = hosts error_on_undefined_vars = True host_key_checking = False transport = ssh jinja2_extensions = jinja2.ext.do [ssh_connection] ssh_args = -F ssh.config pipelining = True ssh.config (referenced in ansible.cfg). Note that if you have a new enough version of ssh, you can use the -W flag instead of nc: #jumpboxes first (most specific hosts first) Host jumpbox01 10.1.0.10 ControlMaster yes ControlPath ~/.ssh/master-%r@jumpbox01:%p StrictHostkeyChecking no ProxyCommand none Host jumpbox02 10.2.0.10 ControlMaster yes ControlPath ~/.ssh/master-%r@jumpbox02:%p StrictHostkeyChecking no ProxyCommand none Host jumpbox03 10.3.0.10 ControlMaster yes ControlPath ~/.ssh/master-%r@jumpbox03:%p StrictHostkeyChecking no ProxyCommand none # groups of machines that can be accessed by the above jumpboxes Host *.west.domain.com 10.1.0.* ControlMaster no ProxyCommand ssh -S ~/.ssh/master-*@jumpbox01:%p remote nc %h %p Host *.central.domain.com 10.2.0.* ControlMaster no ProxyCommand ssh -S ~/.ssh/master-*@jumpbox02:%p remote nc %h %p Host *.east.domain.com 10.3.0.* ControlMaster no ProxyCommand ssh -S ~/.ssh/master-*@jumpbox03:%p remote nc %h %p # this makes ansible faster by reusing connections Host * ControlMaster auto ControlPersist 300s ControlPath ~/.ssh/ansible-%r@%h:%p Once I have those configs setup, I have to run the following to establish a tunnel to a jumpbox/bastion before I can run ansible: $ ssh -F ssh.config -fN user@jumpbox01 When I run the above, it asks for the password (or uses my SSH key), then SSH goes into the background and then the tunnel is established. I do all of my deployments this way by creating a Jenkins job that establishes the tunnel, runs ansible, then tears down the tunnel using something like: ssh -O exit -TS ~/.ssh/path-to-socket Some of the jumpboxes use dumb passwords, some of them use keys, and one of them requires an RSA token (2-factor auth). For the RSA machine, my Jenkins job presents the user with a form that has 2 fields: 2-Factor Username, and 2-Factor Passcode. The passcode is generated by an RSA token keyfob (or smartphone app). In order to make this work, I had to write a custom expect script because the SSH prompt for the RSA token reads "Enter PASSCODE" instead of "Password" which is what sshpass is hardcoded to look for. Here's my expect script to catch all the variations: #!/usr/bin/env expect set timeout 30 set userhost [lindex $argv 0] spawn ssh -fN -F ssh.config $userhost expect { "Enter PASSCODE:" { send "$env(SSH_PASSWORD)\n" send "\n" } "Password:" { send "$env(SSH_PASSWORD)\n" send "\n" } "password:" { send "$env(SSH_PASSWORD)\n" send "\n" } } sleep 5 I need the sleep 5 at the end of the script as a hack because the jumpbox with RSA token don't establish the control socket until a few seconds after the login happens. If my script exits too soon, then the tunnel won't get established. I'm not sure how to properly deal with this. Like I said, some of the machines that I run ansible on have hardcoded passwords and it works fine when ssh_user and ssh_pass is set as facts for your host. -- You received this message because you are subscribed to the Google Groups "Ansible Project" group. To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscr...@googlegroups.com. To post to this group, send email to ansible-project@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/efa85586-f1de-43f6-827e-8a9a3fdbf13e%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.