Execute multiple commands in a single SSH session?

Hello,

I’m coming from the network admin side, and I am hoping to use Ansible to solve some issues we have (eg Customer calls and says “change the SNMP string on all 300 of our routers/switches. By the way, they’re not all the same vendor”). I have already been able to use Ansible to bulk upgrade routers and switches in the lab prior to new deployments, and it’s been fantastic.

I’m trying to do some quick and dirty things with Ansible right now to do things like the above (I don’t presently have the time to learn to write my own modules which may be able to do this) – I was wondering if it’s possible to use something like the Raw module to SSH to a router/switch, and inside the same session, execute a set of commands. While maybe not elegant or ideal, it would be handy for quick changes.

Right now it looks like if I have a playbook with two tasks (both executing a Raw command), Ansible will login to the host, execute command, logout, and then move to the second task and repeat. To effect config changes though I need to be able to do execute all of the following in a single go:

config t
interface BLAH
shutdown
exit

I am still very, very new to Ansible and have not learned all of its features. Is there a way currently to do something like this inside of Ansible?

Thanks,

Will

You can use “-c ssh” to use OpenSSH vs Paramiko, and then it can use Control Master and Control Persist … this ensures that connections are reused.

hi Michael,

when I add “connection: ssh” in my playbook I get this error:

fatal: [10.10.254.33] => using -c ssh on certain older ssh versions may not support ControlPersist, set ANSIBLE_SSH_ARGS=“” (or ansible_ssh_args in the config file) before running again

in doing some googling, it sounds like my CentOS 6 box comes with a [too] old version of OpenSSH to take advantage of I guess the default Ansible SSH settings?

Thanks,

Will

Correct, CentOS/RHEL 6 don't have a new enough ssh to use control persist.
Not sure if this would be of help:

https://code.google.com/p/cisco-ios-cli-automation/

but you may be able to do what you need through ansible 'local_action:'
calling the above script.... (or something similar)

Romeo

I would use the script module, you might need one per type of host

How can you use script module on network switches??

Unfortunately with raw module you cannot manage network switches. At least you cannot switch to config t mode, which is show stopper in this case. I wish there is some kind of module with Expect script behavior. While there is none, Expect is your friend :slight_smile:

Edgars

sorry, didn’t realize the lack of python

I don’t think you have many options then, aside from expect or similar, cluster ssh and pssh which are less than ideal

About that… Paramiko plays are so slow it’s not even funny. Changing the connection to ‘ssh’ is a huge speed improvement (because of the connection reuse). But the default ‘paramiko’ option leads to very bad initial impressions about Ansible’s speed.

I realize that some people are running systems with too old OpenSSH. But perhaps a new ‘auto’ connection type could be introduced, which autodetects the installed OpenSSH version, and uses it if it’s recent enough (falling back to Paramiko otherwise), and this connection type should be the default. Just a suggestion.

Peter,

I’m actually surprised, most people say that paramiko is faster, until you add ControlMaster to ssh at which they find ssh slightly faster. There have been many tests and benchmarks in the past which confirmed what people were saying, I would be curious why your experience is so different.

Chalk me up as another firmly in the ‘ssh is much faster than paramiko’ camp. All of my experience with ansible thus far has been against a few VMs with VirtualBox as the provider, Ubuntu 13.04 as the host OS, and FreeBSD as the guest OS. SSH w/ControlMaster is significantly faster in my setup.

One of the things that strikes me as inefficient (for any of the protocols) is how many of the core modules handle a list of objects. Some of the package managers support list of packages in a single transaction, but modules like ‘file’ don’t handle the creation of multiple directories without executing a new connection for each item in the list. Then given the speed difference between paramiko and ssh, this really takes a toll.

For instance, given this play (and yes, I know there is a more efficient way to do this):

  • name: Create a bunch of directories
    file: dest={{ item }} state=directory
    with_items:
  • /tmp/a
  • /tmp/b
  • /tmp/z

With paramiko, this takes 2s.

With ssh, this takes 0.38s.

Folks should not use the script module if this behavior is required, all you have to do is run from a newer client.

I am also finding paramiko to be pretty darn zippy.

$ time ansible-playbook -i ansible/vagrant --user=root ansible/site.yml -t users,common,syslimits -c paramiko

real 0m10.449s
user 0m3.720s
sys 0m1.556s

$ time ansible-playbook -i ansible/vagrant --user=root ansible/site.yml -t users,common,syslimits -c ssh

real 0m5.739s
user 0m2.400s
sys 0m2.260s

This shows ‘ssh’ being twice faster than ‘paramiko’, on two Vagrant VMs I use for testing. I’ve excluded tasks which take a long time (e.g. download packages) using the tags, so that we are benchmarking the connections’ performance. With remote machines the difference is greater. The host OS I’m managing from is Kubuntu 13.04, the managed VMs are Ubuntu 12.04.

For many people paramiko is 2x or more faster than -c ssh without ControlMaster.

I’d be curious if you are doing something like trying to manage AWS from outside AWS.

Of course, you can also engage fireball mode if you want :slight_smile:

For many people paramiko is 2x or more faster than -c ssh without ControlMaster.

Ok, but I thought we were specifically discussing ssh with ControlMaster. I.e. using ssh as default only when the autodetected OpenSSH version is new enough to support ControlMaster + ControlPersist.

I’d be curious if you are doing something like trying to manage AWS from outside AWS.

Nope, I left AWS two years ago and I’m never going back. The above times were, as mentioned, on two local Vagrant VMs. I.e. there was no network delay at all.

However, SSH is also faster than Paramiko when used with remote hosts. I just made the same test using two DigitalOcean VPS machines. SSH - 0m20.640s, Paramiko - 0m37.032s.

Of course, you can also engage fireball mode if you want :slight_smile:

For me SSH (not Paramiko) is fast enough that I prefer not to bother with Fireball mode.