<p>Put the template into a <a href="https://yaml.org/spec/1.2.2/#chapter-8-block-style-productions" rel="nofollow noreferrer">block</a>. For example,</p>
<pre class="lang-yaml prettyprint-override"><code>    - set_fact:
        email_machine_list: |-
          {% for host in ansible_play_batch %}
          &lt;b&gt;{{ hostvars[host]['ansible_hostname']|upper }}:&lt;\b&gt;&lt;br&gt;
          {% endfor %}
</code></pre>
<hr>
<sup>
<p>Example of a complete playbook for testing</p>
<p>Given the inventory</p>
<pre class="lang-bash prettyprint-override"><code>shell&gt; cat hosts
host_1 ansible_hostname=10.1.0.11
host_2 ansible_hostname=10.1.0.12
host_3 ansible_hostname=10.1.0.13
</code></pre>
<p>The playbook</p>
<pre class="lang-yaml prettyprint-override"><code>- hosts: host_1,host_2,host_3
  gather_facts: false
  tasks:
    - set_fact:
        email_machine_list: |-
          {% for host in ansible_play_batch %}
          &lt;b&gt;{{ hostvars[host]['ansible_hostname']|upper }}:&lt;\b&gt;&lt;br&gt;
          {% endfor %}
      run_once: true
    - debug:
        var: test
      run_once: true
</code></pre>
<p>gives (abridged)</p>
<pre class="lang-yaml prettyprint-override"><code>TASK [debug] *************************************************
ok: [host_1] =&gt; 
  email_machine_list: |-
    &lt;b&gt;10.1.0.11:&lt;\b&gt;&lt;br&gt;
    &lt;b&gt;10.1.0.12:&lt;\b&gt;&lt;br&gt;
    &lt;b&gt;10.1.0.13:&lt;\b&gt;&lt;br&gt;
</code></pre>
<p>Email</p>
<p>Put the <em>body</em> of the email into the block as well. For example,</p>
<pre class="lang-yaml prettyprint-override"><code>    - name: email the list
      mail:
        to: Me &lt;admin@localhost&gt;
        from: Ansible &lt;ansible@localhost&gt;
        subject: &quot;Ansible Notification&quot;
        subtype: html
        body: |-
          &lt;!DOCTYPE html&gt;
          &lt;html&gt;
          &lt;body&gt;
          &lt;h3&gt;{{ email_machine_list }}&lt;/h3&gt;&lt;br&gt;&lt;br&gt;
          &lt;/body&gt;
          &lt;/html&gt;
        host: localhost
        port: 25
      run_once: true
      delegate_to: localhost
</code></pre>
<p>The email was delivered as expected. I had to turn off the rendering of HTML to text in the email client.</p>
<pre class="lang-bash prettyprint-override"><code>Return-Path: &lt;ansible@localhost&gt;
X-Original-To: admin@localhost
Delivered-To: admin@localhost
Received: from [127.0.0.1] (localhost [127.0.0.1])
 by test.example.org (Postfix) with ESMTPS id 3664C180493
 for &lt;admin@localhost&gt;; Thu,  8 Sep 2022 23:48:00 +0200 (CEST)
Content-Type: multipart/mixed; -charset=&quot;utf-8&quot;; boundary=&quot;===============4465080980945319992==&quot;
MIME-Version: 1.0
From: Ansible &lt;ansible@localhost&gt;
Date: Thu, 08 Sep 2022 23:48:00 +0200
Subject: Ansible Notification
X-Mailer: Ansible mail module
To: Me &lt;admin@localhost&gt;
Cc: 
Message-Id: &lt;20220908214800.3664C180493@test.example.org&gt;


&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
&lt;h3&gt;&lt;b&gt;10.1.0.11:&lt;\b&gt;&lt;br&gt;
&lt;b&gt;10.1.0.12:&lt;\b&gt;&lt;br&gt;
&lt;b&gt;10.1.0.13:&lt;\b&gt;&lt;br&gt;
&lt;/h3&gt;&lt;br&gt;&lt;br&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Enabled rendering of HTML to text works as well</p>
<pre class="lang-bash prettyprint-override"><code>10.1.0.11:
10.1.0.12:
10.1.0.13:
</code></pre>
</sup>

CC BY-SA 4.0
2022-09-08T02:17:00.627Z
Thank you but it still did not work.  I edited my post to include what I am doing with the **email_machine_list** set_fact.  I still get this in my HTML emails:

`HOST1:<\b>`
`user1`
`user2`


`HOST2:<\b>`
`user1`
`user2`


`HOST3:<\b>`
`user1`
`user2`
alteredstate
CC BY-SA 4.0
2022-09-08T03:01:16.527Z
What is preventing you from updating the question with the current status? Minimize it and make it a reproducible example.
Vladimir Botka
CC BY-SA 4.0
2022-09-08T20:17:58.610Z
I edited my original post and added my entire Playbook. Is that what you are asking for?
alteredstate
CC BY-SA 4.0
2022-09-08T21:14:41.977Z
No. It is not. I asked you to "Minimize it and make it a reproducible example". Start with my code and show me how "it still did not work". If you can't, proceed step by step and show the minimal and reproducible example that didn't work and you are not able to fix it. See [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example).
Vladimir Botka
CC BY-SA 4.0
2022-09-08T21:54:23.070Z
I should have included my entire Playbook from the beginning and I see the confusion.  I added some additional information on what I am trying to accomplish.
alteredstate
CC BY-SA 4.0
2022-09-08T22:12:53.727Z
Put the body into the block as well. I added an example. Your problem might be outside Ansible. Probably in the processing or rendering of the message.
Vladimir Botka
CC BY-SA 4.0
2022-09-08T22:15:28.197Z
I put the body of the email in a block but the <\b> is still visible in my email.  Are you able to turn on HTML in your email client and see if it is visible for you as well?
alteredstate
CC BY-SA 4.0
2022-09-08T22:21:05.810Z
WOOWWW, I really messed up and wasted your time so I apologize.  The closing tags are suppose to be forward slashes  </b>!  Once I changed that, everything works!  On a side note, you did show me something about Jinja blocks so I thank you for that!!
alteredstate
CC BY-SA 4.0
2022-09-08T22:22:03.680Z
Minimal! That's what I asked you from the very beginning.
Vladimir Botka
CC BY-SA 4.0
2022-09-08T22:25:35.720Z
It wouldn't have made a difference because I was using the wrong slash.  I didn't notice it until I looked at the <h3> </h3> tags closely.  This is a problem with my eyes and nothing to do with Minimal, Ansible, etc...
alteredstate
CC BY-SA 4.0
2022-09-08T00:29:32.680Z
2022-09-08T22:20:06.220Z
2022-09-08T22:20:06.220Z
Vladimir Botka
<p>I cannot figure out how to escape an HTML closing tag, <strong>&lt;\b&gt;</strong> in this example, when used inside an Ansible Jinja conditional (ansible 2.9.27 in this case). Using an additional backslash <strong>&lt;\\b&gt;</strong> does not work and neither does putting the backslash between single quotes <strong>&lt;'\'b&gt;</strong>.  Anyone have an idea how I can make this work?</p>
<p>Here is my entire Playbook with credentials and email addresses redacted:</p>
<pre><code>- name: GET ADMIN GROUP USERS AND COMMENT (GECOS)
  ansible.builtin.shell: &quot;lslogins --noheadings -g adm -o USER,GECOS|sed s'/$/&lt;br&gt;/'&quot;
  register: lslogins_output
#
# 
- name: FORMAT LIST FOR HTML EMAIL
  ansible.builtin.set_fact:
    email_machine_list:  |-
      {% for host in ansible_play_batch %}
      {% if hostvars[host]['lslogins_output']['stdout'] | length &gt; 0 %}
      &lt;b&gt;{{ hostvars[host]['ansible_hostname']|upper }}:&lt;\b&gt;&lt;br&gt;
      {{ hostvars[host]['lslogins_output']['stdout'] }}&lt;br&gt;&lt;br&gt;
      {% elif hostvars[host]['lslogins_output']['stdout'] | length == 0  %}
      &lt;b&gt;{{ hostvars[host]['ansible_hostname']|upper }}:&lt;\b&gt;&lt;br&gt;
      NO ADMINS FOUND&lt;br&gt;&lt;br&gt;
      {% endif %}
      {% endfor %}
  run_once: true
  delegate_to: localhost
#
#
- name: EMAIL USER LIST
  mail:
    to: Me &lt;me@foo.bar&gt;
    from: Ansible &lt;ansible@foo.bar&gt;
    subject: &quot;Ansible Notification&quot;
    subtype: html
    body:  '&lt;!DOCTYPE html&gt;
           &lt;html&gt;
           &lt;body&gt;
           &lt;h3&gt;{{ email_machine_list }}&lt;/h3&gt;&lt;br&gt;&lt;br&gt;
           &lt;/body&gt;
           &lt;/html&gt;'
    host: mail.foo.bar
    port: 587
    secure: starttls
    password: mypassword
    username: me@foo.bar
  run_once: true
  become: false
  delegate_to: localhost
</code></pre>
<p>The emails I receive from Ansible appear like this.  The &lt;\b&gt; should not appear and should be interpreted as a closing HTML tag:</p>
<pre><code>HOST1:&lt;\b&gt;
syslog
user1


HOST2:&lt;\b&gt;
syslog
user1


HOST3:&lt;\b&gt;
syslog
user1
</code></pre>

<ansible><jinja>
How Can I Escape Backspace Using Set_Fact In Ansible With Jinja Conditional
alteredstate
# How Can I Escape Backspace Using Set_Fact In Ansible With Jinja Conditional

(Asked by: username_0 on 2022-09-07)

I cannot figure out how to escape an HTML closing tag, <\b> in this example, when used inside an Ansible Jinja conditional (ansible 2.9.27 in this case). Using an additional backslash <\\b> does not work and neither does putting the backslash between single quotes <'\'b>.  Anyone have an idea how I can make this work?
Here is my entire Playbook with credentials and email addresses redacted:
- name: GET ADMIN GROUP USERS AND COMMENT (GECOS)
  ansible.builtin.shell: "lslogins --noheadings -g adm -o USER,GECOS|sed s'/$//'"
  register: lslogins_output
#
# 
- name: FORMAT LIST FOR HTML EMAIL
  ansible.builtin.set_fact:
    email_machine_list:  |-
      {% for host in ansible_play_batch %}
      {% if hostvars[host]['lslogins_output']['stdout'] | length > 0 %}
      {{ hostvars[host]['ansible_hostname']|upper }}:<\b>
      {{ hostvars[host]['lslogins_output']['stdout'] }}
      {% elif hostvars[host]['lslogins_output']['stdout'] | length == 0  %}
      {{ hostvars[host]['ansible_hostname']|upper }}:<\b>
      NO ADMINS FOUND
      {% endif %}
      {% endfor %}
  run_once: true
  delegate_to: localhost
#
#
- name: EMAIL USER LIST
  mail:
    to: Me 
    from: Ansible 
    subject: "Ansible Notification"
    subtype: html
    body:  '
           
           
           {{ email_machine_list }}
           
           '
    host: mail.foo.bar
    port: 587
    secure: starttls
    password: mypassword
    username: me@foo.bar
  run_once: true
  become: false
  delegate_to: localhost

The emails I receive from Ansible appear like this.  The <\b> should not appear and should be interpreted as a closing HTML tag:
HOST1:<\b>
syslog
user1


HOST2:<\b>
syslog
user1


HOST3:<\b>
syslog
user1

**Tags:** ansible, jinja


---

## 1 answers

### Answer by username_1 on 2022-09-08. Score: 1

Put the template into a block. For example,
    - set_fact:
        email_machine_list: |-
          {% for host in ansible_play_batch %}
          {{ hostvars[host]['ansible_hostname']|upper }}:<\b>
          {% endfor %}



Example of a complete playbook for testing
Given the inventory
shell> cat hosts
host_1 ansible_hostname=10.1.0.11
host_2 ansible_hostname=10.1.0.12
host_3 ansible_hostname=10.1.0.13

The playbook
- hosts: host_1,host_2,host_3
  gather_facts: false
  tasks:
    - set_fact:
        email_machine_list: |-
          {% for host in ansible_play_batch %}
          {{ hostvars[host]['ansible_hostname']|upper }}:<\b>
          {% endfor %}
      run_once: true
    - debug:
        var: test
      run_once: true

gives (abridged)
TASK [debug] *************************************************
ok: [host_1] => 
  email_machine_list: |-
    10.1.0.11:<\b>
    10.1.0.12:<\b>
    10.1.0.13:<\b>

Email
Put the body of the email into the block as well. For example,
    - name: email the list
      mail:
        to: Me 
        from: Ansible 
        subject: "Ansible Notification"
        subtype: html
        body: |-
          
          
          
          {{ email_machine_list }}
          
          
        host: localhost
        port: 25
      run_once: true
      delegate_to: localhost

The email was delivered as expected. I had to turn off the rendering of HTML to text in the email client.
Return-Path: 
X-Original-To: admin@localhost
Delivered-To: admin@localhost
Received: from [127.0.0.1] (localhost [127.0.0.1])
 by test.example.org (Postfix) with ESMTPS id 3664C180493
 for ; Thu,  8 Sep 2022 23:48:00 +0200 (CEST)
Content-Type: multipart/mixed; -charset="utf-8"; boundary="===============4465080980945319992=="
MIME-Version: 1.0
From: Ansible 
Date: Thu, 08 Sep 2022 23:48:00 +0200
Subject: Ansible Notification
X-Mailer: Ansible mail module
To: Me 
Cc: 
Message-Id: <20220908214800.3664C180493@test.example.org>





10.1.0.11:<\b>
10.1.0.12:<\b>
10.1.0.13:<\b>




Enabled rendering of HTML to text works as well
10.1.0.11:
10.1.0.12:
10.1.0.13:

> **Comments:**
> **username_0**: Thank you but it still did not work.  I edited my post to include what I am doing with the **email_machine_list** set_fact.  I still get this in my HTML emails:  `HOST1:<\b>` `user1` `user2`   `HOST2:<\b>` `user1` `user2`   `HOST3:<\b>` `user1` `user2`  
> **username_1**: What is preventing you from updating the question with the current status? Minimize it and make it a reproducible example.  
> **username_0**: I edited my original post and added my entire Playbook. Is that what you are asking for?  
> **username_1**: No. It is not. I asked you to "Minimize it and make it a reproducible example". Start with my code and show me how "it still did not work". If you can't, proceed step by step and show the minimal and reproducible example that didn't work and you are not able to fix it. See [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example).  
> **username_0**: I should have included my entire Playbook from the beginning and I see the confusion.  I added some additional information on what I am trying to accomplish.  
> **username_1**: Put the body into the block as well. I added an example. Your problem might be outside Ansible. Probably in the processing or rendering of the message.  
> **username_0**: I put the body of the email in a block but the <\b> is still visible in my email.  Are you able to turn on HTML in your email client and see if it is visible for you as well?  
> **username_0**: WOOWWW, I really messed up and wasted your time so I apologize.  The closing tags are suppose to be forward slashes  </b>!  Once I changed that, everything works!  On a side note, you did show me something about Jinja blocks so I thank you for that!!  
> **username_1**: Minimal! That's what I asked you from the very beginning.  
> **username_0**: It wouldn't have made a difference because I was using the wrong slash.  I didn't notice it until I looked at the <h3> </h3> tags closely.  This is a problem with my eyes and nothing to do with Minimal, Ansible, etc...  

---

