[GH-ISSUE #254] Cisco IOS supported? #69

Closed
opened 2026-05-07 00:18:21 +02:00 by BreizhHardware · 11 comments

Originally created by @dwydler on GitHub (Oct 15, 2021).
Original GitHub issue: https://github.com/ovh/the-bastion/issues/254

Hi Guys,
we use The Bastion in combination with Ansible via the Ansible Wrapper extension. Not only for administration but also to distribute configurations (e.g. SNMP). This works fine in combination with Debian and Ubuntu Server.

We are currently trying to do the same with Cisco Catalyst devices (IOS). We have set up a very simple example for testing.

This is our Inventory:

all:
  hosts:
    # Cisco IOS
    switch01:
      ansible_host: 192.168.0.1
      ansible_network_os: ios

children:
    switches:
      hosts:
        switch01:

This this our playbook:

---
- hosts: switches
  gather_facts: false
  connection: ansible.netcommon.network_cli

  tasks:
    - name: Run cli_command on Cisco IOS and display results
      block:
      - name: Run cli_command on Cisco IOS
        ansible.netcommon.cli_command:
          command: show ip int br
        register: result

This this our group_vars:

bastion_user: ansible
bastion_host: bastion.domain.com
bastion_port: 22

ansible_connection: network_cli
ansible_user: admin
ansible_network_os: ios
ansible_become: yes
ansible_become_method: enable

ansible_ssh_transfer_method: scp
ansible_ssh_pipelining: 1
ansible_ssh_executable: /home/ansible/AnsibleConfig/library/the-bastion/sshwrapper.py

ansible_scp_if_ssh: True
ansible_scp_executable: /home/ansible/AnsibleConfig/library/the-bastion/scpbastion.sh

This is our displayed error output:

354093 1634323654.86474: host switch01 is done iterating, returning The full traceback is:
  File "/tmp/ansible_ansible.netcommon.cli_command_payload_tb3lyzxx/ansible_ansible.netcommon.cli_command_payload.zip/ansible_collections/ansible/netcommon/plugins/modules/cli_command.py", line 170, in main
  File "/tmp/ansible_ansible.netcommon.cli_command_payload_tb3lyzxx/ansible_ansible.netcommon.cli_command_payload.zip/ansible/module_utils/connection.py", line 200, in __rpc__
    raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [switch01]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "answer": null,
            "check_all": false,
            "command": "show ip int br",
            "newline": true,
            "prompt": null,
            "sendonly": false
        }
    },
    "msg": "command timeout triggered, timeout value is 30 secs.\nSee the timeout setting options in the Network Debug and Troubleshooting Guide."
}

Ansible version:

ansible [core 2.11.6] 
  config file = /home/ansible/.ansible.cfg
  configured module search path = ['/home/ansible/AnsibleConfig/library']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, Sep 28 2021, 16:10:42) [GCC 9.3.0]
  jinja version = 2.10.1
  libyaml = True

Can someone give me a push on what I'm doing wrong?

Originally created by @dwydler on GitHub (Oct 15, 2021). Original GitHub issue: https://github.com/ovh/the-bastion/issues/254 Hi Guys, we use The Bastion in combination with Ansible via the Ansible Wrapper extension. Not only for administration but also to distribute configurations (e.g. SNMP). This works fine in combination with Debian and Ubuntu Server. We are currently trying to do the same with Cisco Catalyst devices (IOS). We have set up a very simple example for testing. This is our Inventory: ``` all: hosts: # Cisco IOS switch01: ansible_host: 192.168.0.1 ansible_network_os: ios children: switches: hosts: switch01: ``` This this our playbook: ``` --- - hosts: switches gather_facts: false connection: ansible.netcommon.network_cli tasks: - name: Run cli_command on Cisco IOS and display results block: - name: Run cli_command on Cisco IOS ansible.netcommon.cli_command: command: show ip int br register: result ``` This this our group_vars: ``` bastion_user: ansible bastion_host: bastion.domain.com bastion_port: 22 ansible_connection: network_cli ansible_user: admin ansible_network_os: ios ansible_become: yes ansible_become_method: enable ansible_ssh_transfer_method: scp ansible_ssh_pipelining: 1 ansible_ssh_executable: /home/ansible/AnsibleConfig/library/the-bastion/sshwrapper.py ansible_scp_if_ssh: True ansible_scp_executable: /home/ansible/AnsibleConfig/library/the-bastion/scpbastion.sh ``` This is our displayed error output: ``` 354093 1634323654.86474: host switch01 is done iterating, returning The full traceback is: File "/tmp/ansible_ansible.netcommon.cli_command_payload_tb3lyzxx/ansible_ansible.netcommon.cli_command_payload.zip/ansible_collections/ansible/netcommon/plugins/modules/cli_command.py", line 170, in main File "/tmp/ansible_ansible.netcommon.cli_command_payload_tb3lyzxx/ansible_ansible.netcommon.cli_command_payload.zip/ansible/module_utils/connection.py", line 200, in __rpc__ raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code) fatal: [switch01]: FAILED! => { "changed": false, "invocation": { "module_args": { "answer": null, "check_all": false, "command": "show ip int br", "newline": true, "prompt": null, "sendonly": false } }, "msg": "command timeout triggered, timeout value is 30 secs.\nSee the timeout setting options in the Network Debug and Troubleshooting Guide." } ``` Ansible version: ``` ansible [core 2.11.6] config file = /home/ansible/.ansible.cfg configured module search path = ['/home/ansible/AnsibleConfig/library'] ansible python module location = /usr/lib/python3/dist-packages/ansible ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections executable location = /usr/bin/ansible python version = 3.8.10 (default, Sep 28 2021, 16:10:42) [GCC 9.3.0] jinja version = 2.10.1 libyaml = True ``` Can someone give me a push on what I'm doing wrong?
Author
Owner

@speed47 commented on GitHub (Oct 20, 2021):

Hello,

Can you run it with -vvv? Ansible should dump way more info that should help pinpoint the problem

<!-- gh-comment-id:947598753 --> @speed47 commented on GitHub (Oct 20, 2021): Hello, Can you run it with `-vvv`? Ansible should dump way more info that should help pinpoint the problem
Author
Owner

@speed47 commented on GitHub (Oct 20, 2021):

Btw, yes Cisco IOS is supported: we have workflows that use it daily on thousands of devices, however I think nobody tested the combo Ansible + Cisco IOS yes. However I don't see any reason as to why it wouldn't work.

<!-- gh-comment-id:947600043 --> @speed47 commented on GitHub (Oct 20, 2021): Btw, yes Cisco IOS is supported: we have workflows that use it daily on thousands of devices, however I think nobody tested the combo Ansible + Cisco IOS yes. However I don't see any reason as to why it wouldn't work.
Author
Owner

@dwydler commented on GitHub (Oct 20, 2021):

we have workflows that use it daily on thousands of devices,

Which tool do you use for the workflow, puppet?

<!-- gh-comment-id:947883578 --> @dwydler commented on GitHub (Oct 20, 2021): > we have workflows that use it daily on thousands of devices, Which tool do you use for the workflow, puppet?
Author
Owner

@speed47 commented on GitHub (Oct 21, 2021):

we have workflows that use it daily on thousands of devices,

Which tool do you use for the workflow, puppet?

No, as Puppet has a reverse workflow logic compared to Ansible: the puppet agent installed on the host pulls data from the puppet master and applies the needed changes. The puppet master never needs to have SSH access to any of its agents.

In that case I was referring to business workflows, implemented through homemade code in Python, Golang, or any other language. But it doesn't mean Ansible should not work ;) did you have a chance to run it in very verbose mode?

<!-- gh-comment-id:948406673 --> @speed47 commented on GitHub (Oct 21, 2021): > > we have workflows that use it daily on thousands of devices, > > Which tool do you use for the workflow, puppet? No, as Puppet has a reverse workflow logic compared to Ansible: the puppet agent installed on the host pulls data from the puppet master and applies the needed changes. The puppet master never needs to have SSH access to any of its agents. In that case I was referring to business workflows, implemented through homemade code in Python, Golang, or any other language. But it doesn't mean Ansible should not work ;) did you have a chance to run it in very verbose mode?
Author
Owner

@dwydler commented on GitHub (Oct 21, 2021):

did you have a chance to run it in very verbose mode?

Yes, i did it today. How can i sent you the logfile? I don't want to post the output publicly. Otherwise i have to mask all internal data.

<!-- gh-comment-id:948977589 --> @dwydler commented on GitHub (Oct 21, 2021): > did you have a chance to run it in very verbose mode? Yes, i did it today. How can i sent you the logfile? I don't want to post the output publicly. Otherwise i have to mask all internal data.
Author
Owner

@speed47 commented on GitHub (Oct 27, 2021):

Sorry, I was sure I had answered this one: you can send it by e-mail to the address you get from:
git log | grep bastion@ | head -n1
(trying to avoid spambots ;) )

<!-- gh-comment-id:953006095 --> @speed47 commented on GitHub (Oct 27, 2021): Sorry, I was sure I had answered this one: you can send it by e-mail to the address you get from: `git log | grep bastion@ | head -n1` (trying to avoid spambots ;) )
Author
Owner

@dwydler commented on GitHub (Oct 27, 2021):

No problem. I wrote you an email.

<!-- gh-comment-id:953151780 --> @dwydler commented on GitHub (Oct 27, 2021): No problem. I wrote you an email.
Author
Owner

@dwydler commented on GitHub (Nov 8, 2021):

Did you find the time to look into the logfiles?

<!-- gh-comment-id:963481130 --> @dwydler commented on GitHub (Nov 8, 2021): Did you find the time to look into the logfiles?
Author
Owner

@speed47 commented on GitHub (Nov 10, 2021):

Yes, did it just now, thanks for the e-mail.
So, the links you've found and indicated in the email (in addition to the log) were a good hint about where the problem lies, and your debug logs does confirm that. For completeness sake, the links were:

https://twitter.com/vince2_/status/1279402577919201281
https://github.com/ansible/ansible/issues/54981

Indeed it seems that this particular ansible module, network_cli, is not using the normal 'ssh' ansible module, but the 'paramiko_ssh' module instead (in the logs you provided, we can see both modules loaded, probably 'ssh' is used by the ansible core in all cases). Paramiko is a Python ssh lib which doesn't use the system's ssh binary, so AFAIK there's no way to easily "hook" into it and use the wrappers.

I think we already had people using paramiko here (not through an Ansible module, but in a custom python code), and we found no way to use it without actually patching Paramiko itself. I think today we no longer use it.

So, that would explain why it probably won't work with network_cli, unfortunately. However, maybe it would just work with the plain ssh module directly? As the bastion handles the SSH negotiation on the egress side, including potentially typing passwords where ssh keys are not supported, it might work?

<!-- gh-comment-id:965428952 --> @speed47 commented on GitHub (Nov 10, 2021): Yes, did it just now, thanks for the e-mail. So, the links you've found and indicated in the email (in addition to the log) were a good hint about where the problem lies, and your debug logs does confirm that. For completeness sake, the links were: https://twitter.com/vince2_/status/1279402577919201281 https://github.com/ansible/ansible/issues/54981 Indeed it seems that this particular ansible module, network_cli, is not using the normal 'ssh' ansible module, but the 'paramiko_ssh' module instead (in the logs you provided, we can see both modules loaded, probably 'ssh' is used by the ansible core in all cases). Paramiko is a Python ssh lib which doesn't use the system's ssh binary, so AFAIK there's no way to easily "hook" into it and use the wrappers. I think we already had people using paramiko here (not through an Ansible module, but in a custom python code), and we found no way to use it without actually patching Paramiko itself. I think today we no longer use it. So, that would explain why it probably won't work with network_cli, unfortunately. However, maybe it would just work with the plain ssh module directly? As the bastion handles the SSH negotiation on the egress side, including potentially typing passwords where ssh keys are not supported, it might work?
Author
Owner

@dwydler commented on GitHub (Nov 15, 2021):

Thanks for your time.

However, maybe it would just work with the plain ssh module directly?

In my opinion that means a bash is expected ?! Which is not the case with Cisco IOS devices.
So in this case we will connect directly to the switches without bastion. :-(

<!-- gh-comment-id:969363568 --> @dwydler commented on GitHub (Nov 15, 2021): Thanks for your time. > However, maybe it would just work with the plain ssh module directly? In my opinion that means a bash is expected ?! Which is not the case with Cisco IOS devices. So in this case we will connect directly to the switches without bastion. :-(
Author
Owner

@speed47 commented on GitHub (Dec 21, 2021):

Added an FAQ entry for this: https://ovh.github.io/the-bastion/faq.html#can-i-use-ansible-over-the-bastion

<!-- gh-comment-id:998792797 --> @speed47 commented on GitHub (Dec 21, 2021): Added an FAQ entry for this: https://ovh.github.io/the-bastion/faq.html#can-i-use-ansible-over-the-bastion
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/the-bastion#69
No description provided.