lineinfile module: multiline from stdout is automatically wrapped in quotes

816 views
Skip to first unread message

Synaesthete

unread,
Aug 2, 2014, 12:26:54 PM8/2/14
to ansible...@googlegroups.com
Some quick background. I'm using ansible to automate setup of development environments for new projects. These are active development environments, not freshly provisioned machines, so some challenges come with the territory--in particular there are times when I would use a template to configure a new machine, but in an active dev environment I have to modify existing config files.

In one case I am configuring the ~/.ssh/config file to make it possible to SSH in to a vagrant box using a regular 'ssh vagrantguest' by taking the resulting config block from 'vagrant ssh-config'. This is a multi-line block. I have a playbook that does something like this:

- name: Retrieve ssh config from vagrant
  shell
: vagrant ssh-config --host vagrantguest chdir={{ project_path }}
  changed_when
: False
 
register: vagrant_ssh_config

- name: Add ssh config to ~/.ssh/config
  lineinfile
: path=~/.ssh/config line={{ vagrant_ssh_config.stdout }} regexp="^Host vagrantguest\n.*\n"

The variable, vagrant_ssh_config.stdout is added to the file but is surrounded in single-quotes. Is this a bug or expected behavior? Is there a way to remove these quotes? Or is there a better solution to this altogether?

Amr Ali

unread,
Aug 2, 2014, 1:16:59 PM8/2/14
to ansible...@googlegroups.com
This is strange, does the output itself have the quotes or it gets added by jinja? can you post the "vagrant_ssh_config" output?

maybe you can try doing this it will stop jinja from automatically escaping your variables based on your environment :

{{ vagrant_ssh_config.stdout | safe }}


Michael DeHaan

unread,
Aug 2, 2014, 2:24:44 PM8/2/14
to ansible...@googlegroups.com
Let me know what version of Ansible you are running?

In light of some security fixes, it took a few revs to nail quoting in some cases.

All being said, 1.6.10 is good stuff on that front.   




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/62c15bc7-768e-485c-8850-557c4ef14251%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Synaesthete

unread,
Aug 2, 2014, 2:42:13 PM8/2/14
to ansible...@googlegroups.com
I checked and on a debug message do not see single-quotes in the stdout. Adding the | safe also didn't help. So it seems that still either jinja or ansible is throwing single-quotes around the variable data before writing it to file. I don't see this same behavior when writing the same block using the template module, so this may be specific to lineinfile.

I'm running the most recent build, v1.7

Amr Ali

unread,
Aug 2, 2014, 3:20:15 PM8/2/14
to ansible...@googlegroups.com
maybe it's because of the multiline output? 

you should try it with stdout_lines instead of stdout, you'd probably have to change your regexp parameter to an insertafter 

- name: Add ssh config to ~/.ssh/
config
  lineinfile
: path=~/.ssh/config line={{ item }} insertafter="^Host vagrantguest\n.*\n"
  with_items
: vagrant_ssh_config.stdout_lines


Synaesthete

unread,
Aug 2, 2014, 4:18:38 PM8/2/14
to ansible...@googlegroups.com
Good tip. I did manage to get this to work and had to add an extra step to make sure that first "Host vagrant" line is there. My tasks look like this and work fine in ansible 1.7:

---

- name: Retrieve ssh config from
vagrant
  shell
: vagrant ssh-config --host vagrant chdir={{ project_path }}
  changed_when
: False
 
register: vagrant_ssh_config

- name: Add config header
  lineinfile
: dest=~/.ssh/config line="Host vagrant" create=yes state=present

- name: Add ssh config to ~/.ssh/
config
  lineinfile
: dest=~/.ssh/config line="{{ item }}" insertafter="Host vagrant"
  with_items
: vagrant_ssh_config.stdout_lines


If the lineinfile module correctly processed newline characters (in the regexp= argument as well) and didn't add the surrounding quotes to multiline strings this could be done in two steps and likely resolve a few edge cases.  In particular the procedure I'm using may produce unwanted lines if my vagrant ssh-config output changes.

Amr Ali

unread,
Aug 2, 2014, 4:33:25 PM8/2/14
to ansible...@googlegroups.com
glad it worked for you, someone more experienced with the code can probably tell why it's wrapping multilines in quotes, not sure if it's a python thing or an issue with the lineinfile module or even with how ansible registers multiline outputs.

if you have the time maybe you can test something - not even sure if this will work haven't tried joining jinja varaibles using a newling before..

- name: Add ssh config to ~/.ssh/
config
  lineinfile
: path=~/.ssh/config line={{ vagrant_ssh_config.stdout_lines | join('\n') }} regexp="^Host vagrantguest\n.*\n"


Reply all
Reply to author
Forward
0 new messages