# deferred evaluation (?)

**URL:** <https://forum.ansible.com/t/deferred-evaluation/38270>\
**Category:** Ansible Project\
**Created:** [July 27, 2023, 8:22pm UTC](https://forum.ansible.com/t/deferred-evaluation/38270 "2023-07-27T20:22:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [July 27, 2023, 8:22pm UTC](https://forum.ansible.com/t/deferred-evaluation/38270/1 "2023-07-27T20:22:38Z")

</div>

I’m trying to loop over a set of strings with ansible.builtin.debug, and I want to produce a three-part message for each string, like this:

- name: Demo expressions  
ansible.builtin.debug:  
msg:
- ‘{{ item }}’
- ‘_evaluate item as a Jinja2 expression_’
- ‘_like previous, but with “| bool” appended_’  
loop:
- “0”
- “1”
- “2”
- “[‘aa’, ‘bb’, ‘cc’] | intersect([‘bb’, ‘cc’])”
- “[‘aa’, ‘bb’, ‘cc’] | intersect([‘bb’, ‘cc’]) | length \> 0”

The first part of the message should show the string, and it does.  
The second part somehow needs to show the result of evaluating the string as a Jinja2 expression.  
The third part is supposed to append “| bool” onto the string, evaluate _that_ as a Jinja2 expression, and show the result.

I feel like there should be some way to do this with lookup(‘items’,…), but I’m having no luck. I’d appreciate any suggestions. Thanks,

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [July 27, 2023, 8:51pm UTC](https://forum.ansible.com/t/deferred-evaluation/38270/2 "2023-07-27T20:51:59Z")

</div>

try the template lookup

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [July 27, 2023, 9:18pm UTC](https://forum.ansible.com/t/deferred-evaluation/38270/3 "2023-07-27T21:18:39Z")

</div>

I’m confused. The template lookup wants a [list of] file[s]. I’d rather not write these strings out to temp files just to get them templated. Or am I misinterpreting your suggestion?

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [July 27, 2023, 10:03pm UTC](https://forum.ansible.com/t/deferred-evaluation/38270/4 "2023-07-27T22:03:22Z")

</div>

post expected result

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [July 28, 2023, 12:54am UTC](https://forum.ansible.com/t/deferred-evaluation/38270/5 "2023-07-28T00:54:03Z")

</div>

Sure. Here’s a complete example where the debug task’s output msg contains exactly what I want. However, instead of each item being a 3-element list of strings, I want to pass in a single string, and use that string in various ways within the msg: expressions to accomplish the same thing.

To be clear: as presented below, this problem isn’t worth solving. After all, there’s the playbook down below already! But that’s not the point. The point is to understand effective _run-time_ techniques to build strings containing Jinja2 expressions and have them evaluated. (“Templated” I guess is the verb rather than “evaluated,” but that feels backwards. In my brain, “to template” means to examine a sufficiently large set of outputs and create a template adequate to reproduce those outputs from reasonable inputs. But I digress.)

Apparently it’s possible to write such strings to a file and use lookup(‘template’,tmpfilename), but there doesn’t seem to be the equivalent of lookup(‘template’,jinja2\_expression\_string). Not that I have found anyway.

```auto
[utoddl@tango ansible]$ **cat deferred.yml** 
---
# deferred.yml
- name: Deferred evaluation demo
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Evaluate booleanness of various expressions
      ansible.builtin.debug:
        msg:
          - '{{ item.0 }}'
          - '{{ item.1 }}'
          - '{{ item.2 }}'
      loop:
        - [ "0",
           "{{ 0 }}",
           "{{ 0 | bool }}"]
        - [ "1",
           "{{ 1 }}",
           "{{ 1 | bool }}"]
        - [ "2",
           "{{ 2 }}",
           "{{ 2 | bool }}"]
        - ["['aa', 'bb', 'cc'] | intersect(['bb', 'cc'])",
           "{{ ['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) }}",
           "{{ ['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | bool }}"]
        - ["['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | length > 0",
           "{{ ['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | length > 0 }}",
           "{{ ['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | length > 0 | bool }}"]
[utoddl@tango ansible]$ **ansible-playbook deferred.yml**

PLAY [Deferred evaluation demo] *************************************************************************

TASK [Evaluate booleanness of various expressions] ******************************************************
ok: [localhost] => (item=['0', '0', False]) => {
    "msg": [
        "0",
        "0",
        false
    ]
}
ok: [localhost] => (item=['1', '1', True]) => {
    "msg": [
        "1",
        "1",
        true
    ]
}
ok: [localhost] => (item=['2', '2', False]) => {
    "msg": [
        "2",
        "2",
        false
    ]
}
ok: [localhost] => (item=["['aa', 'bb', 'cc'] | intersect(['bb', 'cc'])", ['bb', 'cc'], False]) => {
    "msg": [
        "['aa', 'bb', 'cc'] | intersect(['bb', 'cc'])",
        [
            "bb",
            "cc"
        ],
        false
    ]
}
ok: [localhost] => (item=["['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | length > 0", True, True]) => {
    "msg": [
        "['aa', 'bb', 'cc'] | intersect(['bb', 'cc']) | length > 0",
        true,
        true
    ]
}

PLAY RECAP **********************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0   

```

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [July 28, 2023, 3:27am UTC](https://forum.ansible.com/t/deferred-evaluation/38270/6 "2023-07-28T03:27:31Z")

</div>

Create a template. For example,

> cat create\_test.j2

{% for i in strings %}  
{{ i }} = {{ '{{' }} {{ i }} {{ '}}' }}  
{% endfor %}

Then, the below playbook

> cat pb.yml

- hosts: localhost  
&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;- template:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src: create\_test.j2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest: /tmp/test.j2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strings:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- '0'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- '1'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "['aa', 'bb', 'cc']|intersect(['bb', 'cc'])"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "['aa', 'bb', 'cc']|intersect(['bb', 'cc'])|length \> 0"  
&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ lookup('template', '/tmp/test.j2') }}"

gives abridged

&nbsp;&nbsp;msg: |-  
&nbsp;&nbsp;&nbsp;&nbsp;0 = 0  
&nbsp;&nbsp;&nbsp;&nbsp;1 = 1  
&nbsp;&nbsp;&nbsp;&nbsp;['aa', 'bb', 'cc']|intersect(['bb', 'cc']) = ['bb', 'cc']  
&nbsp;&nbsp;&nbsp;&nbsp;['aa', 'bb', 'cc']|intersect(['bb', 'cc'])|length \> 0 = True
