Reputation: 72
Problem: I've got 2 tasks that are executed sequentially as (expected) given the Ansible nature. As I understand, you can only execute one module per each task.
Task 1 - Gather facts information (serials, versions, etc) from network devices.
Task 2 - Render a template with the info gathered in Task1
Ideal Result: Since I'm looping through loads of network devices my ideal result would be to choose one device at a time, gather the information from it and then render a template with that information, next go to the other device on the loop and so on.
Approach: I've thought to keep the same syntax, On task 1 save the facts on a file (.json) and on task 2, read the JSON file and get the variables I'm interested in.
Is there any better way to do this? (Probably there's more than one)
What I've got currently doesn't fit my purpose as when the template renders, it only contains information about the last device:
Tasks: roles/juniper.junos/tasks/main.yaml
- name: 1 - Gathering Facts
junos_get_facts:
host: "{{ inventory_hostname}}"
user: ""
passwd: ""
savedir: "~/Ansible/Ouput/Facts"
ignore_errors: True
register: junos
- name: 2 - Creating the template
template:
src="~/Ansible/roles/juniper.junos/templates/template.j2"
dest="~/Ansible/Ouput/Facts/Device_facts.yml"
Template: ~/Ansible/roles/juniper.junos/templates/template.j2
{% for host in groups['OOB_AMS'] %}
ANSIBLE NAME: {{ inventory_hostname}}
HOSTNAME: {{ junos.facts.hostname }}
MODEL: {{ junos.facts.model }}
SERIAL: {{ junos.facts.serialnumber }}
VERSION: {{ junos.facts.model }}
UP TIME: {{ junos.facts.RE0.up_time }}
{% endfor %}
IDEAL Output:"~/Ansible/Ouput/Facts/Device_facts.yml"
ANSIBLE NAME: DEVICE 1
HOSTNAME: DEVICE 1 HOSTNAME
MODEL: DEVICE 1 MODEL
SERIAL: DEVICE 1 SERIAL
VERSION: DEVICE 1 VERSION
UP TIME: DEVICE 1 UP TIME
ANSIBLE NAME: DEVICE 2
HOSTNAME: DEVICE 2 HOSTNAME
MODEL: DEVICE 2 MODEL
SERIAL: DEVICE 2 SERIAL
VERSION: DEVICE 2 VERSION
UP TIME: DEVICE 2 UP TIME
ANSIBLE NAME: DEVICE 3
HOSTNAME: DEVICE 3 HOSTNAME
MODEL: DEVICE 3 MODEL
SERIAL: DEVICE 3 SERIAL
VERSION: DEVICE 3 VERSION
UP TIME: DEVICE 3 UP TIME
Upvotes: 0
Views: 2838
Reputation: 68639
You wrote a for
-loop with a host
variable, but not used it even once.
Change the template to:
{% for host in ansible_play_hosts %}
ANSIBLE NAME: {{ hostvars[host].inventory_hostname}}
HOSTNAME: {{ hostvars[host].junos.facts.hostname }}
MODEL: {{ hostvars[host].junos.facts.model }}
SERIAL: {{ hostvars[host].junos.facts.serialnumber }}
VERSION: {{ hostvars[host].junos.facts.model }}
UP TIME: {{ hostvars[host].junos.facts.RE0.up_time }}
{% endfor %}
Looping over groups['OOB_AMS']
was not bad, but hardcoding group name seems unnecessary for your case. Instead you can use: ansible_play_hosts
(play_hosts
before version 2.2).
Also for clarity you might add run_once: true
to the template
task. This is not critical, because the template generates the same output in each iteration, so the subsequent runs will be skipped anyway, but there is no need to do it several times.
Upvotes: 2