lineinfile 'new line' broken for yaml format

I am trying to add the following to the bottom of my /etc/tower/settings.py file (note the new line):

AWX_TASK_ENV[‘ANSIBLE_LIBRARY’] = ‘/etc/ansible/library/’

So I wrote the following in my playbook:

example 1

lineinfile:
dest: /etc/tower/settings.py
line: ‘\nAWX_TASK_ENV[’‘ANSIBLE_LIBRARY’‘] = ‘’/etc/ansible/library/’‘’
state: present

This doesn’t work. I end up with the following in my file:

\nAWX_TASK_ENV[‘ANSIBLE_LIBRARY’] = ‘/etc/ansible/library/’

The \n has been written rather than a new line.

So I changed my playbook to this:

example 2

lineinfile: dest=/etc/tower/settings.py line=‘\nAWX_TASK_ENV[’‘ANSIBLE_LIBRARY’‘] = ‘’/etc/ansible/library/’‘’ state=present

Now I have the following in my file:

AWX_TASK_ENV[ANSIBLE_LIBRARY] = /etc/ansible/library/

The new line has been correctly added but it has stripped my quotes.

I just wanted to get a better understanding of why the different way of writing a module task behave differently and what is the Ansible-recommended way of writing them?

Further, is there a way to make what I’m trying to do work? Does my first example need to be raised as a bug and in the meantime, is there a way to quote my second example so that it works as I expected?

Sorry if this seems more like a user-group post but i just wanted to get some idea about the history of writing module tasks and how it evolved and why they behave differently.

line: ‘\nAWX_TASK_ENV[’‘ANSIBLE_LIBRARY’‘] = ‘’/etc/ansible/library/’‘’

Try double quotes: “\nfoo”

Cheers,
Paul

If i double quoted it I would of expected the response I actually got. Indeed, with double quotes the result is the same.

*bump*

Any feedback from Ansible core guys in the difference in behaviour between value= and value: ?

Hi Rob,

So inorder to process a task ansbile splits the task into ‘action’ (module_name) and ‘args’ (arguments to the task).
The ‘args’ needs to be a dictionary/hash.
so if we specify the task as (also called complex args)

  • lineinfile:
    line=foo
    state=present.

in yaml this is a list item with key=lineinfile and value a dictionary {line: foo, state: present}, and while parsing ansible get the args easily as it is already a dictionary.

when the task is defined as

  • lineinfile: line=foo state=present

in yaml this become key=lineinfile and value is string ‘line=foo state=present’, Here ansible parses this string through a method split_args to convert this string to a dictionary equivalent to {line: foo, state: present}

In your case an extra "" is added by yaml because you have quoated with single quotes, which make yaml treat all the characters as strings special characters are ignored.
line: ‘\nAWX_TASK_ENV[’‘ANSIBLE_LIBRARY’‘] = ‘’/etc/ansible/library/’‘’

if you replace the above with double quotes, yaml preserves the special charactercts like \n so if you change to this it shoudl work:
line: "\nAWX_TASK_ENV[‘ANSIBLE_LIBRARY’] = ‘/etc/ansible/library/’ "

when you changed to lineinfile: line=foo method still yaml will add the additional \ but it is stripped by the split_args method.

i think even with change the lines might get readded as it would not have a match in the next run due to the \n.

Hope this helps.

  • Benno