Reputation: 31
Can anyone help me with a command running on a legacy network device (switch) from an Ansible (v2.5) connection? Because the network device is legacy I cannot use an Ansible module, which is why I have to resort to raw. Also, it is worth pointing out that I have no control over the legacy device - I cannot replace it with a more up-to-date model, or alter the configuration in any but the most trivial ways.
The Ansible command I want to run is quite basic. Something like this (obviously not this, in reality the command is 'nsshow', but I don't want to focus on that as I am sure there will be other commands with the same problem):
- name: "Device Command"
raw: "command1"
register: command
That does work, but not in the way required. The problem is that the command runs in the wrong context on the target device, so even though the command runs successfully the output it produces is not useful.
I have done some investigation with SSH commands to discover the nature of the problem. Initially I tried using SSH to connect to the device and entering the command manually. That worked, and I could see from the command prompt on the device that the command was running in the correct context. The next thing I tried was running the command as a pipeline. I found that the first of these commands didn't work (in the same way as Ansible), but that the second worked correctly:
echo -e "command1" | ssh myaccount@mydevice
echo -e "command1" | ssh -tt myaccount@mydevice
So, it seems that the problem relates to pseudo terminals. I realised I needed the -tt option when the first command gave a warning error 'Pseudo-terminal will not be allocated because stdin is not a terminal'. Going back to the Ansible command I can see that if I run Ansible with verbose output that -tt is used on the SSH command line. So why doesn't the Ansible command work? I then discovered that this command also hits the warning error problem when run from the command line:
ssh -tt myaccount@mydevice command1
I think that is more like what Ansible is doing than the pipeline examples I used above and that this explains why Ansible is not working.
Of course within Ansible I can run the command like this, which does work, but I'd rather avoid it.
- name: "Device Command"
local_action:
module: shell echo -e "command1" | ssh -tt myaccount@{{ inventory_hostname }}
register: command
So, the actual question is 'how can I run an Ansible play that runs a raw command on the target device that avoids the psuedo terminal issue'?
Thanks in advance for any help or suggestions.
Upvotes: 0
Views: 920
Reputation: 68469
You can always add ansible_ssh_args
to your play:
- hosts: legacy_device
vars:
ansible_ssh_args: -tt
tasks:
- name: "Device Command"
raw: "command1"
register: command
or better yet to the inventory, or host_vars, or group_vars.
Upvotes: 1