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 [email protected].
To post to this group, send email to [email protected].
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.