Unable to open shell: Ansible v2.3.1.0

2019-07-29 16:35发布

问题:

So I use Ansible day-to-day to manage our AWS instances and now I'm testing out managing our network infrastructure (I'm a Network guy, who can do some system admin stuff) but have run into a problem that I can't seem to get around.

I have a Cisco 3750G here that I've enabled SSH on. I can ssh in with the specified user and run all the commands that are failing in my playbook.

I'm able to use the ping module successfully from Ansible to this switch but whenever I try to use the ios_commands or ios_configs modules it fails with the errorunable to open shell.

I'm using Ansible v2.3.1.0 which has persistent connections as a new feature. Done some googling and I've found a few people who have had this issue and have fixed it in various ways (none of which worked for me).

Things I've tried:

  • Specified the connection variables in a secrets.yaml file. Then specified the provider using my username, auth_pass, and password in the secrets file.
  • Changing the ansible_connection setting to local and ssh (neither worked)
  • Disabled host_key_checking for now in my ansible.cfg file

After that didnt work I tried: - Manually creating the provider connection variables in the playbook itself. - Used 2 different modules ios_commands and ios_configs (there's some
difference between the 2 modules but for my use both should act the same)

https://docs.ansible.com/ansible/network_debug_troubleshooting.html#category-unable-to-open-shell This doc states that the error I'm seeing is normally an authentication issue but that doesnt seem to be the case here.

Anyone else run into this or have any insight ? I have a log file with the debug output from my playbook run if anyone wants to view that. I've posted my sample playbook below for review.

hosts: switch gather_facts: no connection: local tasks:

- name: GATHER CREDENTIALS
  include_vars: secrets.yaml

- name: DEFINE CONNECTION PROVIDER
  set_fact:
    provider:
      username: "{{ creds['username'] }}"
      password: " {{ creds['password'] }}"
      auth_pass: "{{ creds['auth_pass'] }}"

- name: Show interfaces
  ios_config:
    provider: "{{ provider }}"
    commands:
      - show ip int br
  register: cisco_int

- debug: var=cisco_int.stdout_lines

回答1:

I finally figured out what was happening here. It was a combination of things.

  • The persistent connection feature of 2.3 is broken for me so I had to downgrade to 2.2.0.0

  • Then I had to manually specify my python interpreter in my inventory. Apparently you can install paramiko in a way that doesnt install it to /usr/bin/python but instead goes to /usr/local/bin/python, the former being where Ansible runs its modules from.

  • I also thought wrong that the behavior of ios_command and ios_config were similar. config is used for commands in global/interface config mode. command runs from user and priv exec mode.

Now my playbook runs and I can get the output of show ip int br on my 3750.



回答2:

I know you said you downgraded. Maybe this helps if you decide to give 2.3 another shot. I had a somewhat same issue while moving from 2.2 to 2.3 I am running my basic playbook with the following format. Although in my TACACS setup I don't use enable secrets I included the option.

hosts

[ios:vars]
ansible_python_interpreter=/usr/bin/python
ansible_connection = local
# If SSH/ For Telnet - Port=23
port=22
[ios]
ios-swt-1
ios-rtr-1

secrets.yml

---
creds:
 username: ansible
 password: '@ns1Bl3'
#Uncomment For Enable:
#auth_pass: 3n@bl3

Playbook

---
- hosts: ios
  gather_facts: no
  connection: local

  tasks:

  - name: obtain login credentials
    include_vars: secrets.yml

  - name: define provider
    set_fact:
      provider:
        host: "{{ inventory_hostname }}"
        username: "{{ creds['username'] }}"
        password: "{{ creds['password'] }}"
        #Uncomment next line if enable password is needed
        #auth_pass: "{{ creds['auth_pass'] }}"
        transport: cli

  - include: tasks/ios_command-freeform.yml

tasks/ios_command-freeform.yml

---
- name: Freeform Task
  ios_command:
    provider: "{{ provider }}"
    commands:
# Change the command after "-" to any IOS command you would like to run.
      - show version
  register: freeform

# Provides an output if -vvv is not used when running ansible-playbook
- debug: var=freeform.stdout_lines

- name: append to output
# append the command output to a local file
  copy:
    content: "{{ freeform.stdout[0] }}"
    dest: "play_results/{{ inventory_hostname }}.txt"


标签: ansible cisco