Ansible ios playbook to gather IOS runinng config of diferents hosts to files - ansible

I'm looking to create a playbook on ansible to gather info of more than 300 hosts and save the info to a file. I get 2 diffente issues, one not being able to save the info to a file and the second issue comes because of telnet connection of some hosts, only working for ssh hosts.
ansible 2.9.3
under vm CentOS7
Already tried:
- name: "[SCAN][IOS] IOS play for scanning facts"
hosts: CISCO
connection: network_cli
ignore_errors: true
ignore_unreachable: true
vars:
ansible_network_os: ios
gather_facts: False
tasks:
- name: run show logging host ip on remote devices
ios_command:
commands: show run | i logging host
register: output
- debug:
var: output["stdout_lines"]
This playbook shows the ssh hosts results according to the configuration required, but I'm not able to save this info to a file.
On the other hand I would like to run this commands on telnet hosts, is it possible to run this in both connection types together and save to file?

Related

Ansible: Host localhost is unreachable

In my job there is a playbook developed in the following way that is executed by ansible tower.
This is the file that ansible tower executes and calls a playbook
report.yaml:
- hosts: localhost
gather_facts: false
connection: local
tasks:
- name: "Execute"
include_role:
name: 'fusion'
main.yaml from fusion role:
- name: "hc fusion"
include_tasks: "hc_fusion.yaml"
hc_fusion.yaml from fusion role:
- name: "FUSION"
shell: ansible-playbook roles/fusion/tasks/fusion.yaml --extra-vars 'fusion_ip_ha={{item.ip}} fusion_user={{item.username}} fusion_pass={{item.password}} fecha="{{fecha.stdout}}" fusion_ansible_become_user={{item.ansible_become_user}} fusion_ansible_become_pass={{item.ansible_become_pass}}'
fusion.yaml from fusion role:
- hosts: localhost
vars:
ansible_become_user: "{{fusion_ansible_become_user}}"
ansible_become_pass: "{{fusion_ansible_become_pass}}"
tasks:
- name: Validate
ignore_unreachable: yes
shell: service had status
delegate_to: "{{fusion_user}}#{{fusion_ip_ha}}"
become: True
become_method: su
This is a summary of the entire run.
Previously it worked but throws the following error.
stdout: PLAY [localhost] \nTASK [Validate] [1;31mfatal: [localhost -> gandalf#10.66.173.14]: UNREACHABLE! => {\"changed\": false, \"msg\": \"Failed to connect to the host via ssh: Warning: Permanently added '10.66.173.14' (RSA) to the list of known hosts.\ngandalf#10.66.173.14: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password), \"skip_reason\": \"Host localhost is unreachable\"
When I execute ansible-playbook roles/fusion/tasks/fusion.yaml --extra-vars XXXXXXXX from the command line with user awx it works.
Also I validated the connection from the server where ansible tower is running to where you want to connect with the ssh command and if it allows me to connect without requesting a password with the user awx
fusion.yaml does not explicitly specify connection plugin, thus default ssh type is being used. For localhost this approach usually brings a number of related problems (ssh keys, known_hosts, loopback interfaces etc.). If you need to run tasks on localhost you should define connection plugin local just like in your report.yaml playbook.
Additionally, as Zeitounator mentioned, running one ansible playbook from another with shell model is a really bad practice. Please, avoid this. Ansible has a number of mechanism for code re-use (includes, imports, roles etc.).

using netconf_get in an ansible playbook

I am testing out using netconf via Ansible and I keep getting this error when running the playbook:
ansible.module_utils.connection.ConnectionError:
AuthenticationException('Authentication timeout.',)
I am ablte to use ssh over port 830 to my Cisco device from the scripting server:
ssh cisco#10.1.1.1 -p 830 -s netconf
This is the playbook:
---
- name: My Playbook
hosts: 'my_host'
gather_facts: false
tasks:
- name: Execute the get_config RPC
netconf_get:
display: json
register: result
- name: Print the configuration as JSON
debug:
var: result.output
And the inventory is something like this:
[my_lab:children]
my_lab_iosxr
[my_lab:vars]
look_for_keys = False
host_key_checking = False
ansible_ssh_pass = 'cisco'
ansible_user = 'cisco'
[my_lab_iosxr]
my_host ansible_host=10.1.1.1 ansible_network_os=iosxr ansible_connection=netconf
I should add, I see this error on the console of the cisco device when attempting the play above:
Sep 8 17:37:42.218 UTC: SSHD_[67398]: %SECURITY-SSHD-3-ERR_GENERAL :
Failed to receive User authentication request
Looks like I have found the answer to my own question.
I decided to just write my own netconf module in python and I was getting the same error.
So I switched to using python installed on another machine and the same code works.
Seems like there is an issue with the version of python installed on that server...

Ansible Synchronize module stuck while testing

Goal: I'm trying to copy /home/foo/certificates/*/{fullchain.cer,*.key}
from one server (tower.example.com) to other nodes.
When trying the task with verbose options, it's stuck. Output logs can be found there (Ansible 2.5): https://gist.github.com/tristanbes/1be96509d4853d647a49d30259672779
- hosts: staging:web:tower:!tower.example.com
gather_facts: yes
become: yes
become_user: foo
tasks:
- name: synchronize the certificates folder
synchronize:
src: "/home/foo/certificates/"
dest: "{{ certificates_path }}/"
rsync_opts:
- "--include=fullchain.cer"
- "--include=*.key"
delegate_to: tower.example.com
I'm running this playbook on localhost.
What I except of this is to connect as foo on tower.example.com then, to ssh as foo to servers of groups web and staging to rsync push the content of the folder matching the filters.
I can run other playbooks on tower.example.com
I can connect on tower.example.com with my user and then sudo -i && su foo to foo.
As foo, I can connect to other hosts as foo for servers under group web and staging.
What am I missing?
It looks like tower.example.com may not have ssh access to the other hosts. This would cause Ansible to get stuck as ssh is waiting for a password. You can fix this by
generating a new ssh key on tower.example.com and authorizing it on the other hosts, and/or
setting up ssh-agent forwarding.
Alternatively, you could fetch the certificates to a temp folder on localhost and copy them to the other hosts. This avoids the use of delegate_to, but is not as efficient as syncing the files directly between the remote hosts.

How to create a file locally with ansible templates on the development machine

I'm starting out with ansible and I'm looking for a way to create a boilerplate project on the server and on the local environment with ansible playbooks.
I want to use ansible templates locally to create some generic files.
But how would i take ansible to execute something locally?
I read something with local_action but i guess i did not get this right.
This is for the webbserver...but how do i take this and create some files locally?
- hosts: webservers
remote_user: someuser
- name: create some file
template: src=~/workspace/ansible_templates/somefile_template.j2 dest=/etc/somefile/apps-available/someproject.ini
You can delegate tasks with the param delegate_to to any host you like, for example:
- name: create some file
template: src=~/workspace/ansible_templates/somefile_template.j2 dest=/etc/somefile/apps-available/someproject.ini
delegate_to: localhost
See Playbook Delegation in the docs.
If your playbook should in general run locally and no external hosts are involved though, you can simply create a group which contains localhost and then run the playbook against this group. In your inventory:
[local]
localhost ansible_connection=local
and then in your playbook:
hosts: local
Ansible has a local_action directive to support these scenarios which avoids the localhost and/or ansible_connection workarounds and is covered in the Delegation docs.
To modify your original example to use local_action:
- name: create some file
local_action: template src=~/workspace/ansible_templates/somefile_template.j2 dest=/etc/somefile/apps-available/someproject.ini
which looks cleaner.
If you cannot do/allow localhost SSH, you can split the playbook on local actions and remote actions.
The connection: local says to not use SSH for a playbook, as shown here: https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html#local-playbooks
Example:
# myplaybook.yml
- hosts: remote_machines
tasks:
- debug: msg="do stuff in the remote machines"
- hosts: 127.0.0.1
connection: local
tasks:
- debug: msg="ran in local ansible machine"
- hosts: remote_machines
tasks:
- debug: msg="do more stuff in remote machines"

Ansible - actions BEFORE gathering facts

Does anyone know how to do something (like wait for port / boot of the managed node) BEFORE gathering facts? I know I can turn gathering facts off
gather_facts: no
and THEN wait for port but what if I need the facts while also still need to wait until the node boots up?
Gathering facts is equivalent to running the setup module. You can manually gather facts by running it. It's not documented, but simply add a task like this:
- name: Gathering facts
setup:
In combination with gather_facts: no on playbook level the facts will only be fetched when above task is executed.
Both in an example playbook:
- hosts: all
gather_facts: no
tasks:
- name: Some task executed before gathering facts
# whatever task you want to run
- name: Gathering facts
setup:
Something like this should work:
- hosts: my_hosts
gather_facts: no
tasks:
- name: wait for SSH to respond on all hosts
local_action: wait_for port=22
- name: gather facts
setup:
- continue with my tasks...
The wait_for will execute locally on your ansible host, waiting for the servers to respond on port 22, then the setup module will perform fact gathering, after which you can do whatever else you need to do.
I was trying to figure out how to provision a host from ec2, wait for ssh to come up, and then run my playbook against it. Which is basically the same use case as you have. I ended up with the following:
- name: Provision App Server from Amazon
hosts: localhost
gather_facts: False
tasks:
# #### call ec2 provisioning tasks here ####
- name: Add new instance to host group
add_host: hostname="{{item.private_ip}}" groupname="appServer"
with_items: ec2.instances
- name: Configure App Server
hosts: appServer
remote_user: ubuntu
gather_facts: True
tasks: ----configuration tasks here----
I think the ansible terminology is that I have two plays in a playbook, each operating on a different group of hosts (localhost, and the appServer group)

Resources