# escaping curly braces in lineinfile module

**URL:** <https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915>\
**Category:** Ansible Project\
**Created:** [May 12, 2020, 7:32pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915 "2020-05-12T19:32:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Laci](https://avatars.discourse-cdn.com/v4/letter/l/c67d28/32.png) [@Laci](https://forum.ansible.com/u/Laci)\
**Post date:** [May 12, 2020, 7:32pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/1 "2020-05-12T19:32:11Z")

</div>

I am new in Ansible world. I spent some time solving this but got to the point when I need to ask:  
I have a file called jobs.inc and I need to add six lines with Ansible.

Here is an example  
% cat jobs.inc

Job {  
Name = “server1”  
Client = “server1-fd”  
JobDefs = “DefaultJob”  
}  
Job {  
Name = “server2”  
Client = “server2-fd”  
JobDefs = “DefaultJob”  
}

How would I add server3?

The following playbooks are the ones I tried and they didn’t work. Thank you!

1. 

- name: add new lines to jobs.inc  
lineinfile:  
path: /conf.d/jobs.inc  
line: “{{ item }}”  
with\_items:
- Job {% raw %}{{% endraw %}
- Name = “{{ remote\_shorthost }}”
- Client = “{{ remote\_shorthost }}-fd”
- JobDefs = “DefaultJob”
- {% raw %}}{% endraw %}

1. 

- name: add new lines to jobs.inc  
lineinfile:  
path: /conf.d/jobs.inc  
line: “{{ item }}”  
with\_items:
- Job {
- Name = “{{ remote\_shorthost }}”
- Client = “{{ remote\_shorthost }}-fd”
- JobDefs = “DefaultJob”
- }

1. 

vars:  
curly1\_variable: !unsafe ‘{’  
curly2\_variable: !unsafe ‘}’  
tasks:

- name: add new lines to jobs.inc

lineinfile:  
path: /conf.d/jobs.inc  
line: “{{ item }}”  
with\_items:

- Job !unsafe curly1\_variable
- Name = “{{ remote\_shorthost }}”
- Client = “{{ remote\_shorthost }}-fd”
- JobDefs = “DefaultJob”
- !unsafe curly2\_variable

---

<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:** [May 12, 2020, 7:47pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/2 "2020-05-12T19:47:11Z")

</div>

The best option in this case would be "template"  
[https://docs.ansible.com/ansible/latest/modules/template\_module.html#template-template-a-file-out-to-a-remote-server](https://docs.ansible.com/ansible/latest/modules/template_module.html#template-template-a-file-out-to-a-remote-server)

If the editing can't be avoided then "blockinfile" might do the job  
[https://docs.ansible.com/ansible/latest/modules/blockinfile\_module.html](https://docs.ansible.com/ansible/latest/modules/blockinfile_module.html)

HTH,

&nbsp;&nbsp;-vlado

---

<div class="post-metadata">

**Author:** ![Laci](https://avatars.discourse-cdn.com/v4/letter/l/c67d28/32.png) [@Laci](https://forum.ansible.com/u/Laci)\
**Post date:** [May 12, 2020, 8:42pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/3 "2020-05-12T20:42:00Z")

</div>

Thank you vlado, this worked for me:

blockinfile:  
path: /conf.d/jobs.inc  
marker: " "  
block: |  
Job {  
Name = “{{ remote\_shorthost }}”  
Client = “{{ remote\_shorthost }}-fd”  
JobDefs = “DefaultJob”  
}  
backup: yes

---

<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:** [May 13, 2020, 3:46am UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/4 "2020-05-13T03:46:45Z")

</div>

> Thank you vlado, this worked for me:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;blockinfile:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path: /conf.d/jobs.inc  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marker: " "  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block: |  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Job {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "{{ remote\_shorthost }}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "{{ remote\_shorthost }}-fd"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "DefaultJob"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;backup: yes

You're welcome, Laci. It's necessary to add that the task is not idempotent.  
It will repeatedly add the same block into the file. Quoting from  
"blockinfile" parameter "marker":  
[https://docs.ansible.com/ansible/latest/modules/blockinfile\_module.html#parameter-marker](https://docs.ansible.com/ansible/latest/modules/blockinfile_module.html#parameter-marker)

&nbsp;&nbsp;"Using a custom marker without the {mark} variable may result in the block  
&nbsp;&nbsp;&nbsp;being repeatedly inserted on subsequent playbook runs."

Best practice is to make the "marker" unique. For example

&nbsp;&nbsp;&nbsp;&nbsp;- blockinfile:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path: jobs.inc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marker: "# {mark} {{ remote\_shorthost }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Job {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "{{ remote\_shorthost }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "{{ remote\_shorthost }}-fd"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "DefaultJob"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;backup: yes

would create (if the variable "remote\_shorthost: server3")

&nbsp;&nbsp;&nbsp;&nbsp;\> cat jobs.inc  
&nbsp;&nbsp;&nbsp;&nbsp;Job {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "server1"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "server1-fd"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "DefaultJob"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;Job {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "server2"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "server2-fd"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "DefaultJob"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;# BEGIN server3  
&nbsp;&nbsp;&nbsp;&nbsp;Job {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "server3"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "server3-fd"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "DefaultJob"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;# END server3

Such marker makes the task idempotent and also helps to create a loop, if  
needed. For example

&nbsp;&nbsp;&nbsp;&nbsp;- blockinfile:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path: jobs.inc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marker: "# {mark} {{ item.remote\_shorthost }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Job {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = "{{ item.remote\_shorthost }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client = "{{ item.remote\_shorthost }}-fd"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JobDefs = "{{ item.jobdefs }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;backup: yes  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop: "{{ my\_servers }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_servers:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- remote\_shorthost: server3  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobdefs: DefaultJob  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- remote\_shorthost: server4  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobdefs: DefaultJob

Fit the first character(s) of the marker to the comment syntax of the language  
the block shall be included in.

HTH,

&nbsp;&nbsp;-vlado

---

<div class="post-metadata">

**Author:** ![Laci](https://avatars.discourse-cdn.com/v4/letter/l/c67d28/32.png) [@Laci](https://forum.ansible.com/u/Laci)\
**Post date:** [May 14, 2020, 2:31pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/5 "2020-05-14T14:31:36Z")

</div>

Actually this is my goal.  
We are going to have add new servers every time to this file.

So the following lines will be repeated X times  
Job {  
Name = “serverX”  
Client = “serverX-fd”  
JobDefs = “DefaultJob”  
}

---

<div class="post-metadata">

**Author:** ![Laci](https://avatars.discourse-cdn.com/v4/letter/l/c67d28/32.png) [@Laci](https://forum.ansible.com/u/Laci)\
**Post date:** [May 14, 2020, 3:16pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/6 "2020-05-14T15:16:20Z")

</div>

Another task I’m working on is a conditional blockinfile, something like:  
if OS=BSD do this, if Linux do that.

I need this because there is a slightly different configuration for them:

BSD:  
Job {  
Name = “serverX”  
Client = “serverX-fd”  
JobDefs = “DefaultJob”  
}

Linux:  
Job {  
Name = “serverX”  
Client = “serverX-fd”  
JobDefs = “DefaultJob”  
FileSet = “linux”  
}

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [May 14, 2020, 3:23pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/7 "2020-05-14T15:23:13Z")

</div>

> Another task I'm working on is a conditional blockinfile, something like:  
> if OS=BSD do this, if Linux do that.
> 
> I need this because there is a slightly different configuration for them:
> 
> BSD:  
> Job {  
> Name = "serverX"  
> Client = "serverX-fd"  
> JobDefs = "DefaultJob"  
> }
> 
> Linux:  
> Job {  
> Name = "serverX"  
> Client = "serverX-fd"  
> JobDefs = "DefaultJob"  
> FileSet = "linux"  
> }

Sorry but I would really use a template instead of shoehorn your syntax with blockinfile.

Regards  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Racke

---

<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:** [May 14, 2020, 3:44pm UTC](https://forum.ansible.com/t/escaping-curly-braces-in-lineinfile-module/32915/8 "2020-05-14T15:44:27Z")

</div>

Include OS-specific variables from the files. For example,

- name: "Vars from {{ playbook\_dir}}/vars/defaults"  
&nbsp;&nbsp;include\_vars: "{{ item }}"  
&nbsp;&nbsp;with\_first\_found:  
&nbsp;&nbsp;&nbsp;&nbsp;- files:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "{{ ansible\_distribution }}-{{ ansible\_distribution\_release }}.yml"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "{{ ansible\_distribution }}.yml"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "{{ ansible\_os\_family }}.yml"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "default.yml"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "defaults.yml"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paths: "{{ playbook\_dir }}/vars/defaults"

FWIW. See  
[https://github.com/vbotka/ansible-lib/blob/master/tasks/al\_include\_os\_vars\_playbook\_dir.yml](https://github.com/vbotka/ansible-lib/blob/master/tasks/al_include_os_vars_playbook_dir.yml)
