Ansible Cisco output creating empty file - linux

Only output from the first command is written to the file.
How do I make it write output from all of the commands to the file?
---
- name: run show commands
hosts: nexus1
gather_facts: False
tasks:
- name: run show commands on nexus
nxos_command:
commands:
- show hostname
- show ip route
- show interface
- show ip interface vrf all
- show hsrp
register: output
- name: Copy to server
copy:
content: "{{ output.stdout[0] }}"
dest: "/home/CiscoOutPut/{{ inventory_hostname }}.txt"

You're only asking for output from the first command. output.stdout is a list, one item for the output of each command. When ask for output.stdout[0], you're asking for only the first result.
If you want to write the output of all commands to a file, then something like:
- name: Copy to server
copy:
content: "{{ '\n'.join(output.stdout) }}"
dest: "/home/CiscoOutPut/{{ inventory_hostname }}.txt"

Related

Ansible loop over multiple lists of variables

i hope everyone can help me with my ansible task problem. I deploy the snmp configurations via ansible on my servers and work with snmp-extend to trigger my scripts over snmp with certain OIDs. After my playbook has run and ansible deploy the snmp configurations, i manually execute the following command to become the OID for certain extend, for example:
snmptranslate -On NET-SNMP-EXTEND-MIB::nsExtendOutput1Line.\"folder-size-/home\"
This part i would like to do automatically via ansible, i have the variables:
snmp_mountpoints_extends:
- folder-size
- folder-avail
- folder-used
and in my inventory I define for host the following variables:
server1:
custom_mountpoints:
- /home
- /opt
my ansible part:
name: Generate OIDs for custom inventroy variables
become: yes
shell: 'snmptranslate -On NET-SNMP-EXTEND-MIB::nsExtendOutput1Line.\"{{ item }}-{{ custom_mountpoints[0] }}\"'
with_items:
"{{ snmp_mountpoints_extends }}"
register: custom_mountpoints_output
when:
- custom_mountpoints is defined
- name: print output from custom_mountpoints_output
debug: msg={{ custom_mountpoints_output }}
This work fine but only for first host variable /home. How can I iterate over my custom_mountpoints with each vars from snmp_mountpoints_extends?
thank you in advance
According Ansible documentation Iterating over nested lists you may use the following approach
---
- hosts:localhost
become: false
gather_facts: false
vars:
server1:
custom_mountpoints:
- /home
- /opt
snmp_mountpoints_extends:
- folder-size
- folder-avail
- folder-used
tasks:
- name: Iterating over nested lists
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
loop: "{{ server1.custom_mountpoints | product(snmp_mountpoints_extend) | list }}"
resulting into the desired output.
/home and folder-size
/home and folder-avail
/home and folder-used
/opt and folder-size
/opt and folder-avail
/opt and folder-used

ansible + how to run ansible interactive like bash script that ask questions

we want to create ansible code that ask interactive questions like the bash script
for now we have the following bash script, with diff 43 Questions , that finally create ini file according to our Questions
bash /home/gentwo.bash
how many machines?23
how many datanode services?
IP address for first machine - andnenda01?
.
.
.
---
as we know we cant do the same with ansible as the following:
- hosts: 17.12.22.56
gather_facts: yes
vars:
app_name: interactive process
ansible_user: root
ansible_password: XXXXXXXXXXX
tasks:
- name: interactive process
script: "/home/gentwo.bash"
register: results
so what is the equivalent approach with ansible?
You can use prompts for interactive input
e.g. from docs:
---
- hosts: all
vars_prompt:
- name: username
prompt: What is your username?
private: no
- name: password
prompt: What is your password?
tasks:
- name: Print a message
ansible.builtin.debug:
msg: 'Logging in as {{ username }}'
Ansible Doc: https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html

How to extract path from Ansible Output and use it else where within my playbook?

I want to extract the path out of the output given by the below command:
Command:
/opt/myapp/dir/bin/client -a 8101 -h localhost -u user -p pass properties-global-export
Output:
client: JAVA_HOME not set; results may vary
Exporting file: org.fusesource.fabric.agent.properties
Exporting file: local.app.node.vendor.service4.properties
Exporting file: local.app.node.data.service3.properties
Exporting file: local.app.node.vendor.service1.properties
Exporting file: local.app.node.vendor.service2.properties
Files dumped into directory: /opt/myapp/install-node/node-2.1.11/data/properties-tmp
and use /opt/myapp/install-node/node-2.1.11/data/properties-tmp path to perform a copy command within my playbook.
- name: Export Properties File
no_log: true
shell: "{{ fuse_esb_client_dir }} -h localhost -a {{ karaf_port }} -u {{ karaf_user }} -p {{ karaf_pass }} properties-global-export | grep -o '\''/[^ ]*'\ "
register: temp
- set_fact:
tempPath: "{{ temp.stdout }}"
- name: All Files Exported To Path
debug: var=temp.stdout
- name: Backup All Property Files to {{ backup_location }}
command: cp -r "{{ tempPath }}" "{{ backup_location }}"
Piped the output to grep grep -o '\''/[^ ]*'\ " The Extra '\' and \ on the start and end is used to escape the regex characters within the playbook. (Remove These if you want to test in your cli)
This Gave Me This Output
/opt/myapp/install-node/node-2.1.11/data/properties-tmp
Dumped that output with set_fact and used it within my playbook.
Hopefully someone finds this usefull. :))) Also for the pros like Jeff :) please let me know if I can improve anything within my playbook.

Ansible playbook to create output to logfile

This is one little part of my working ansible playbook.
I want to send the information which will be gathered to a log file (which the playbook will create)
I have tried so many different way but getting no where.
No error is coming back which can only tell me that the script is working but I guess its going somewhere else other than the destination which I would like it to do
Here is my script
Would be grateful of your thoughts and help
- name: netstat check
shell: netstat -tulnp | awk '{print $4}' | sed -n 's/.*:\([^",]*\)[",]*$/\1/p'
register: netstat
- name: copy output to local file
copy:
content: "{{ netstat.stdout}}"
dest: "/home/user_name/netstat.txt"
Thanks
I executed your playbook in my ansible server(hosts: localhost) and it works fine. A new file is created with the required output.
Incase you want it on the localhost, try giving delegate_to: localhost
- name: copy output to local file
copy:
content: "{{ netstat.stdout}}"
dest: "/home/user_name/netstat.txt"
delegate_to: localhost

Iterating Ansible setup command

I want to use ansible setup module to retrieve hosts specs and I tried with a bash for loop.
Ansible version: 2.4
My hosts inventory has been defined in a group of machines which I called rhelmachines
I would like to collect the following list of variables called "specs"
declare -a specs=("ansible_all_ipv4_addresses" "ansible_processor" "ansible_processor_cores" "ansible_uptime_seconds")
I am then trying to include the ansible command in a for bash loop:
for i in "${specs[#]}"
do
ansible rhelmachines -m setup -a 'filter='$i'
done
how can I concatenate multiple filters in one connection only ?
Thanks!
With a little sed hackery to convert ansible's output to JSON, you can use jq to extract only the pieces you need:
ansible -m setup localhost | sed -e 's/^[[:alpha:]].*[|].* [>][>] {$/{/' | jq -n '
[inputs |
.ansible_facts as $facts |
$facts.ansible_hostname as $hostname |
{($hostname): {
"ipv4_addresses": $facts.ansible_all_ipv4_addresses,
"processor": $facts.ansible_processor[0],
"cores": $facts.ansible_processor_cores,
"uptime": $facts.ansible_uptime_seconds}}] | add'
...generates output of the form:
{
"my-current-hostname": {
"ipv4_addresses": [
"192.168.119.129"
],
"processor": "Intel(R) Core(TM) i7-6700HQ CPU # 2.60GHz",
"cores": 1,
"uptime": null
}
}
(run with ansible 1.4.5, which doesn't generate uptime).
As one of the possible solution, I implemented an Ansible code exploiting Ansible facts. I implemented it first gathering the ansible facts. Then, I used a local_action and a loop. The loop indices are the several ansible facts. For every fact I am writing out a line of a file. In this way I am getting a file composed by all the ansible facts I declared in the loop for the rhelmachines.
---
- hosts: rhelmachines
gather_facts: True
tasks:
- name: Gather Facts
setup:
gather_subset=all
register: facts
- debug:
msg: "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"
- name: copy content from facts to output file
local_action:
module: lineinfile
line: "{{ item }}"
path: /tmp/assessments/facts.txt
loop:
- "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"
- "{{ facts.ansible_facts.ansible_all_ipv6_addresses }}"
I took #Luigi Sambolino answer and make it better. His answer was failing on more than one host in the inventory. He proposed using lineinfile which has one con in this situation - every fact that was the same as other machines were omitted. Other drawback was that results wasn't sorted together, all was mixed.
I needed to take some basic information about systems, like IP, OS version, and so on. Here's my playbook:
- hosts: all
gather_facts: true
ignore_unreachable: true
tasks:
- name: get the facts
setup:
gather_subset=all
register: facts
- name: remove file
local_action:
module: file
path: results
state: absent
- name: save results in file
local_action:
module: shell
cmd: echo "{{ item }}" >> results
with_together:
- "{{ facts.ansible_facts.ansible_default_ipv4.address }}"
- "{{ facts.ansible_facts.ansible_architecture }}"
- "{{ facts.ansible_facts.ansible_distribution }}"
- "{{ facts.ansible_facts.ansible_distribution_version }}"
- "{{ facts.ansible_facts.ansible_hostname }}"
- "{{ facts.ansible_facts.ansible_kernel }}"
Now the results look like this:
...
['10.200.1.21', 'x86_64', 'Ubuntu', '18.04', 'bacula', '4.15.18-7-pve']
['10.200.2.53', 'x86_64', 'Ubuntu', '18.04', 'webserver', '4.15.18-27-pve']
...
Square brackets can be deleted by sed and we have a nice CSV file that can be used with any spreadsheet, for example.
specs=( "ansible_all_ipv4_addresses"
"ansible_processor"
"ansible_processor_cores"
"ansible_uptime_seconds" )
args=( )
for spec in "${specs[#]}"; do args+=( -a "$spec" ); done
ansible rhelmachines -m setup "${args[#]}"
...will result in your final command being equivalent to:
ansible rhelmachines -m setup \
-a ansible_all_ipv4_addresses \
-a ansible_processor \
-a ansible_processor_cores \
-a ansible_uptime_seconds

Resources