I have a variable final_delegate
that determines the hosts depending upon user passed parameter -e perform_action=nslookup
- name: "Play 1"
hosts: localhost
tasks:
- set_fact:
final_delegate: "{{ 'localhost' if perform_action in 'telnetcurlnslookuptracerouteget_ip_address' else 'dest_nodes' }}"
- name: "Play 2"
hosts: "{{ hostvars.localhost.final_delegate }}"
tasks:
- name: Run command
ignore_errors: yes
command: ls -ltr /tmp/all.pdf
register: cmdoutput
- name: Creating body template
template:
src: "{{ playbook_dir }}/body.html.j2"
dest: "{{ playbook_dir }}/body.html.tmp"
delegate_to: localhost
Here is my body.html.j2
<tr>
<td>{{ inventory_hostname }}</td>
<td><pre>{{ hostvars.[inventory_hostname].cmdoutput.stdout_lines | join('\n') }}</pre></td>
</tr>
I get the below error:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: </tr>
fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleError: template error while templating string: expected name or number. String: <tr>\n <td>{{ inventory_hostname }}</td>\n <td><pre>{{ hostvars.[inventory_hostname].cmdoutput.stdout_lines | join('\\n') }}</pre></td>\n </tr>\n\n"}
I also tried the following:
1.
<td><pre>{{ hostvars.[hostvars.localhost.final_delegate].cmdoutput.stdout_lines | join('\n') }}</pre></td>
2.
<td><pre>{{ hostvars.['hostvars.localhost.final_delegate'].cmdoutput.stdout_lines | join('\n') }}</pre></td>
Maybe I'm not getting the syntax right. Can you please suggest?
CodePudding user response:
This...
hostvars.[inventory_hostname]
...is not valid Jinja syntax. When referencing a variable attribute, you have two options:
Dot notation:
item.attribute
Bracket notation:
item["attribute"]
When you want to reference an attribute whose name is contained in a variable, you need the second (bracket) syntax, so:
hostvars[inventory_hostname].cmdoutput.stdout_lines
If it helps, this runs without errors when I run it locally (whether or not /tmp/all.pdf
exists):
- name: "Play 1"
hosts: localhost
vars:
perform_action: something
tasks:
- set_fact:
final_delegate: "{{ 'localhost' if perform_action in 'telnetcurlnslookuptracerouteget_ip_address' else 'dest_nodes' }}"
- name: "Play 2"
hosts: "{{ hostvars.localhost.final_delegate }}"
tasks:
- name: Run command
ignore_errors: true
command: ls -ltr /tmp/all.pdf
register: cmdoutput
- name: Creating body template
template:
src: "body.html.j2"
dest: "body.html.tmp"
delegate_to: localhost
Using the fixed template:
<tr>
<td>{{ inventory_hostname }}</td>
<td><pre>{{ hostvars[inventory_hostname].cmdoutput.stdout_lines | join('\n') }}</pre></td>
</tr>
Note that you don't need to use hostvars
in the above template; you could write instead:
<tr>
<td>{{ inventory_hostname }}</td>
<td><pre>{{ cmdoutput.stdout_lines | join('\n') }}</pre></td>
</tr>