<h5 dir="auto">Issue Type:</h5>
<ul dir="auto">
<li><strong>Bug Report</strong></li>
</ul>
<h5 dir="auto">Ansible Version:</h5>
<p dir="auto">Ansible version: <em>1.9.2</em><br>
Jinja2 version: <em>2.8</em></p>
<p dir="auto">Obtained from pip install on OS described hereafter</p>
<h5 dir="auto">Ansible Configuration:</h5>
<p dir="auto">No change.</p>
<h5 dir="auto">Environment:</h5>
<p dir="auto">Ubuntu 14.04.03 LTS, no virtualenv, pip installed</p>
<h5 dir="auto">Summary:</h5>
<p dir="auto">Jinja 2.1 added the possibility to use the variable yielded by a for loop into an included template.</p>
<p dir="auto">From Jinja website (<a href="http://jinja.pocoo.org/docs/dev/templates/#include" rel="nofollow">http://jinja.pocoo.org/docs/dev/templates/#include</a>):</p>
<blockquote>
<p dir="auto">Note<br>
In Jinja 2.0, the context that was passed to the included template did not include variables defined<br>
in the template. As a matter of fact, this did not work:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{% for box in boxes %}
   {% include &quot;render_box.html&quot; %}
{% endfor %}"><pre class="notranslate"><code class="notranslate">{% for box in boxes %}
   {% include "render_box.html" %}
{% endfor %}
</code></pre></div>
<p dir="auto">The included template render_box.html is not able to access box in Jinja 2.0. As of Jinja 2.1,<br>
render_box.html is able to do so.</p>
</blockquote>
<p dir="auto">Although I use Jinja 2.8 (along with Ansible 1.9), this feature is unavailable/broken by the Ansible template module. This report is not a "feature support" request but a "stop breaking a feature" request :)</p>
<h5 dir="auto">Steps To Reproduce:</h5>
<p dir="auto">To reproduce the bug, use the following playbook :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="
---
- hosts: desktop
  gather_facts: no
  vars:
    nom: &quot;Toto!&quot;
    some_list:
      - &quot;elmt 1&quot;
      - &quot;elmt 2&quot;
  tasks:
  - name: &quot;test&quot;
    template: 
      src: /tmp/tmpl
      dest: /tmp/output"><pre class="notranslate"><code class="notranslate">
---
- hosts: desktop
  gather_facts: no
  vars:
    nom: "Toto!"
    some_list:
      - "elmt 1"
      - "elmt 2"
  tasks:
  - name: "test"
    template: 
      src: /tmp/tmpl
      dest: /tmp/output
</code></pre></div>
<p dir="auto">/tmp/tmpl contains:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="hello {{ nom }}
{% for elmt in some_list %}
{% include 'do_smth_with_elmt' with context %}
{% endfor %}"><pre class="notranslate"><code class="notranslate">hello {{ nom }}
{% for elmt in some_list %}
{% include 'do_smth_with_elmt' with context %}
{% endfor %}
</code></pre></div>
<p dir="auto">/tmp/do_smth_with_elmt:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Print {{ elmt }}"><pre class="notranslate"><code class="notranslate">Print {{ elmt }}
</code></pre></div>
<h5 dir="auto">Expected Results:</h5>
<p dir="auto">No error message from Ansible and rendering of the template</p>
<h5 dir="auto">Actual Results:</h5>
<p dir="auto">Output from Ansible is :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="PLAY [desktop] **************************************************************** 

TASK: [test] ****************************************************************** 
fatal: [desktop.local] =&gt; {'msg': &quot;AnsibleUndefinedVariable: One or more undefined variables: 'elmt' is undefined&quot;, 'failed': True}
fatal: [desktop.local] =&gt; {'msg': &quot;AnsibleUndefinedVariable: One or more undefined variables: 'elmt' is undefined&quot;, 'failed': True}

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/user/test.retry

desktop.local              : ok=0    changed=0    unreachable=1    failed=0 "><pre class="notranslate"><code class="notranslate">PLAY [desktop] **************************************************************** 

TASK: [test] ****************************************************************** 
fatal: [desktop.local] =&gt; {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'elmt' is undefined", 'failed': True}
fatal: [desktop.local] =&gt; {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'elmt' is undefined", 'failed': True}

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/user/test.retry

desktop.local              : ok=0    changed=0    unreachable=1    failed=0 
</code></pre></div>
<p dir="auto"><strong>Comment</strong>:<br>
If I had to do some fingerpointing, I would blame the <code class="notranslate">new_context</code> system of the <code class="notranslate">J2Template</code> class:<br>
<a href="https://github.com/ansible/ansible/blob/stable-1.9/lib/ansible/utils/template.py#L212-L213">https://github.com/ansible/ansible/blob/stable-1.9/lib/ansible/utils/template.py#L212-L213</a></p>
<p dir="auto">Since I am totally unfamiliar with Ansible source code, I might be wrong, though.</p>
<p dir="auto">At any rate, the following python script runs flawlessly on my machine:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import jinja2
loader = jinja2.FileSystemLoader('/tmp')
e = jinja2.Environment(loader=loader)
t = e.get_template('tmpl')
print t.render(nom='Toto!', some_list=['elmt1', 'elmt2'])"><pre class="notranslate"><code class="notranslate">import jinja2
loader = jinja2.FileSystemLoader('/tmp')
e = jinja2.Environment(loader=loader)
t = e.get_template('tmpl')
print t.render(nom='Toto!', some_list=['elmt1', 'elmt2'])
</code></pre></div>
<p dir="auto">Thank you.</p>
<p dir="auto">Currently async operations in playbooks and /usr/bin/ansible are duplicating a lot of code. Using async through the API is also very ugly.</p>
<p dir="auto">I've been thinking about this and would propose a method runAsync() on Runner that returns an object with a poll() method and does all the bookkeeping involved. Timing would be external?</p>
<p dir="auto">Async is also not fully integrated in the callback system, this can also be fixed, along with cleaning up the files in ~/.ansible_async.</p>
<p dir="auto">Any feedback? I could probably do this by the weekend.</p>