问题
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 theprovider
using my username, auth_pass, and password in the secrets file. - Changing the
ansible_connection
setting tolocal
andssh
(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
andios_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"
来源:https://stackoverflow.com/questions/44981599/unable-to-open-shell-ansible-v2-3-1-0