<p>The case you describe is not complete. Without the variable <em>var</em> defined you have to see the error message:</p>
<pre class="lang-yaml prettyprint-override"><code>'var'' is undefined
</code></pre>
<p>The below play</p>
<pre class="lang-yaml prettyprint-override"><code>- hosts: localhost

  vars:

    checks:
      - name: &quot;x&quot;
        setting: &quot;y&quot;
        eval: &quot;{{ 'OK' if var == 'x' else 'NOK' }}&quot;

  tasks:

    - include_tasks: do.yml
      loop: &quot;{{ checks }}&quot;

</code></pre>
<p>fails</p>
<pre class="lang-yaml prettyprint-override"><code>fatal: [localhost]: FAILED! =&gt; 
  msg: '[{''name'': ''x'', ''setting'': ''y'', ''eval'': &quot;{{ ''OK'' if var == ''x'' else ''NOK'' }}&quot;}]: ''var'' is undefined'
</code></pre>
<hr>
<p>To answer your question: <em>&quot;How do I make it so that the item.eval is re-evaluated after var is registered?&quot;</em></p>
<p>It is not possible to reevaluate <code>item.eval</code></p>
<hr>
<p>The solution might be to restructure the data. For example,</p>
<pre class="lang-yaml prettyprint-override"><code>    checks:
      - eval:
          x: OK
          default: NOK
      - eval:
          y: OK
          default: NOK
</code></pre>
<p>Then, evaluate the dictionary in the loop. For example,</p>
<pre class="lang-yaml prettyprint-override"><code>shell&gt; cat do.yml
- command: echo x
  register: out

- set_fact:
    result: &quot;{{ result | d([]) + [ res ] }}&quot;
  vars:
    res:
      result: &quot;{{ item.eval[out.stdout] if  out.stdout in item.eval else item.eval.default }}&quot;
</code></pre>
<p>gives</p>
<pre class="lang-yaml prettyprint-override"><code>  result:
  - result: OK
  - result: NOK
</code></pre>
<hr>
<sup>
<p>Example of a complete playbook for testing</p>
<pre class="lang-yaml prettyprint-override"><code>- hosts: localhost

  vars:

    checks:
      - eval:
          x: OK
          default: NOK
      - eval:
          y: OK
          default: NOK

  tasks:

    - include_tasks: do.yml
      loop: &quot;{{ checks }}&quot;

    - debug:
        var: result
</code></pre>
</sup>

CC BY-SA 4.0
2024-09-03T23:53:38.047Z
2024-09-04T00:37:58.690Z
2024-09-04T00:37:58.690Z
Vladimir Botka
<p>I have a sort of configuration vars file through which I'm looping,</p>
<pre><code>checks:
  - name: &quot;x&quot;
    setting: &quot;y&quot;
    eval: &quot;{{ 'OK' if var == 'x' else 'NOK' }}&quot;
</code></pre>
<p>main.yml</p>
<pre><code>- hosts: all
  tasks:
  - name: Loop
    include_tasks: do.yml
    loop: &quot;{{ checks }}&quot;
</code></pre>
<p>Now the issue is that the eval gets templated/expanded as it's entering the loop...</p>
<p>inside do.yml</p>
<pre><code>---
- debug:
    var: item

(shows eval as NOK)

- name: Do stuff
  shell:
  register: var

- name: Save stuff
  set_fact
    result: &quot;{{ result | d([]) + [ res ] }}&quot;
  vars:
    res:
      name: &quot;{{ item.name }}&quot;
      setting: &quot;{{ item.setting }}&quot;
      result: &quot;{{ item.eval }}&quot;
</code></pre>
<p>How do I make it so that the item.eval is re-evaluated after var is registered?
What I'd like even more is if I just provided the string, without the curly brackets in checks.yml file and that would get templated inside the loop. I just can't make it work.</p>

<ansible><python><jinja>
Ansible Jinja2 evaluate string as template
Someboodyh
# Ansible Jinja2 evaluate string as template

(Asked by: username_0 on 2024-09-03)

I have a sort of configuration vars file through which I'm looping,
checks:
  - name: "x"
    setting: "y"
    eval: "{{ 'OK' if var == 'x' else 'NOK' }}"

main.yml
- hosts: all
  tasks:
  - name: Loop
    include_tasks: do.yml
    loop: "{{ checks }}"

Now the issue is that the eval gets templated/expanded as it's entering the loop...
inside do.yml
---
- debug:
    var: item

(shows eval as NOK)

- name: Do stuff
  shell:
  register: var

- name: Save stuff
  set_fact
    result: "{{ result | d([]) + [ res ] }}"
  vars:
    res:
      name: "{{ item.name }}"
      setting: "{{ item.setting }}"
      result: "{{ item.eval }}"

How do I make it so that the item.eval is re-evaluated after var is registered?
What I'd like even more is if I just provided the string, without the curly brackets in checks.yml file and that would get templated inside the loop. I just can't make it work.

**Tags:** ansible, python, jinja


---

## 1 answers

### Answer by username_1 on 2024-09-03. Score: 0

The case you describe is not complete. Without the variable var defined you have to see the error message:
'var'' is undefined

The below play
- hosts: localhost

  vars:

    checks:
      - name: "x"
        setting: "y"
        eval: "{{ 'OK' if var == 'x' else 'NOK' }}"

  tasks:

    - include_tasks: do.yml
      loop: "{{ checks }}"


fails
fatal: [localhost]: FAILED! => 
  msg: '[{''name'': ''x'', ''setting'': ''y'', ''eval'': "{{ ''OK'' if var == ''x'' else ''NOK'' }}"}]: ''var'' is undefined'


To answer your question: "How do I make it so that the item.eval is re-evaluated after var is registered?"
It is not possible to reevaluate item.eval

The solution might be to restructure the data. For example,
    checks:
      - eval:
          x: OK
          default: NOK
      - eval:
          y: OK
          default: NOK

Then, evaluate the dictionary in the loop. For example,
shell> cat do.yml
- command: echo x
  register: out

- set_fact:
    result: "{{ result | d([]) + [ res ] }}"
  vars:
    res:
      result: "{{ item.eval[out.stdout] if  out.stdout in item.eval else item.eval.default }}"

gives
  result:
  - result: OK
  - result: NOK



Example of a complete playbook for testing
- hosts: localhost

  vars:

    checks:
      - eval:
          x: OK
          default: NOK
      - eval:
          y: OK
          default: NOK

  tasks:

    - include_tasks: do.yml
      loop: "{{ checks }}"

    - debug:
        var: result


---

