ansible 1.7.2 with multiline variables using the copy mod's 'content' directive

Hi there!

I noticed that ansible seemed to have done some updating with regards to multiline variables, and I’m a little confused about the way the variables are handled now.

My use case comes from inserting private-key data into an encrypted yaml file via ansible-vault, and printing the contents via copy module’s content directive. This worked great in 1.7.1, but with 1.7.2, it printed an extra newline between each line. Coincidentally, when I next deployed via ansible 1.7.2, my keys weren’t working.

The format is something like:

group_vars/all.yml:

key: |+ -----BEGIN PRIVATE KEY---- (private key)(private key)`
(private key)
-----END PRIVATE KEY-----

`

roles/tasks/main.yml:

`

  • copy: content=“{{ key }}” dest=“/etc/ssl/private/key”

`

1.7.1 (correct):

-----BEGIN PRIVATE KEY---- (private key)``(private key)`` ```(private key)```-----END PRIVATE KEY-----`

`

1.7.2 (incorrect):

-----BEGIN PRIVATE KEY----`

(private key)

(private key)

(private key)

-----END PRIVATE KEY-----

`

While looking through the github issues, there was a ticket that expressed exactly the issue I ran into:
https://github.com/ansible/ansible/issues/9172

And it was resolved by following the ‘long’ format from:
https://github.com/ansible/ansible/issues/9067

roles/tasks/main.yml (long format):

`

Those changes are related to some security fixes and various related changes as a result of those fixes that came later, all aimed at preventing unexpected argument insertion given untrusted data from remote hosts.

So {{ foo }} is a request to insert something into a line, the way you have it above, and then ansible converts that into module arguments.

I have considered just undocumenting the “content” parameter – we’re likely to do that – as I think it leads to some confusing practices, better served by “template” in most cases.

One of those examples is pushing an embedded shell script inside a playbook, when it could have been done in a one-liner with the “script” module.

If you think you can fix it and still keep the argument detection/parsing in place, I’d be interested - but that’s why it was closed with the reasons given, and why I suggested how to avoid this.

The long form is also needed to pass structured data to modules, as is shown with the ec2 examples.

Thanks for the clarification!

I’ll go ahead and use a template instead if that’s what you’re recommending. It makes the most sense to deprecate/undocument content if it’s difficult to rectify strange differences with corner cases like that.

Thanks!

Assuming copy content goes away, is there any way to simplify the template module? Right now if I want to copy a PEM cert from the vault onto a target host, I have to create a set of files such as cert.j2 and key.j2 with contents {{ cert }} and {{ key }} respectively, so now I have to manage two additional files in my repo.

I’m not positive it’s going away, but you can use conditionals in a template, technically, if that helps you out.

Just ran into the same issue. I hope the “content” argument doesn’t go away; it’s very useful for simple things like SSH keys. But maybe you can document that using it with multi-line variables requires the long module syntax.

We’ve got a ticket open on this.

I ran into this issue as well. Changing “copy” to “template” works like a charm!

I just wanted to say I have no problems with this change, the extra templates needed (in a role) doesn’t bother me at all.