escaping curly braces in lineinfile module

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!

  • 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 %}
  • 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”
  • }

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

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

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

HTH,

  -vlado

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

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

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

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

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

    - blockinfile:
        path: jobs.inc
        marker: "# {mark} {{ remote_shorthost }}"
        block: |
          Job {
            Name = "{{ remote_shorthost }}"
            Client = "{{ remote_shorthost }}-fd"
            JobDefs = "DefaultJob"
           }
        backup: yes

would create (if the variable "remote_shorthost: server3")

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

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

    - blockinfile:
        path: jobs.inc
        marker: "# {mark} {{ item.remote_shorthost }}"
        block: |
          Job {
            Name = "{{ item.remote_shorthost }}"
            Client = "{{ item.remote_shorthost }}-fd"
            JobDefs = "{{ item.jobdefs }}"
           }
        backup: yes
      loop: "{{ my_servers }}"
      vars:
        my_servers:
          - remote_shorthost: server3
            jobdefs: DefaultJob
          - remote_shorthost: server4
            jobdefs: DefaultJob

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

HTH,

  -vlado

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”
}

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”
}

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
          Racke

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

- name: "Vars from {{ playbook_dir}}/vars/defaults"
  include_vars: "{{ item }}"
  with_first_found:
    - files:
        - "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
        - "{{ ansible_distribution }}.yml"
        - "{{ ansible_os_family }}.yml"
        - "default.yml"
        - "defaults.yml"
      paths: "{{ playbook_dir }}/vars/defaults"

FWIW. See
https://github.com/vbotka/ansible-lib/blob/master/tasks/al_include_os_vars_playbook_dir.yml