lineinfile module: multiline from stdout is automatically wrapped in quotes

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?

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

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.

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

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
    `

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:

`

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