template requires write permission on parent directory?

I’m using the “template” task to modify a file that I own, and have write permissions on. I’m not using sudo; I’m just running it as my own user.

But I get an error “Destination [parent-dir] not writable.” I’m guessing it’s deleting and re-creating the file. Is there any way to avoid this, or do I need to give my user write permission on the parent directory?

JW

The template module will need permissions to be able to write the template, however the template module is smart enough to not replace the file if the md5sum of the template has not changed.

IIRC, in some cases of sudo usage from non-root an md5sum isn’t possible and it will need to try to overwrite it each time

Hi Michael. My user does have permission to write the file – he just doesn’t have permission to create files in the parent directory, and Ansible is complaining about that.

When the “template” task updates an existing file, does it delete and re-create the file?

JW

Yes, template writes a new file and moves it into place.

I see, thanks. Could this be considered a bug? There may be cases where you want a user to have write permission on a file, but not the whole directory.

it would require a major change to how template/file/assemble/etc work. In template’s case the file is actually generated on the master and copied to the target machine.

ansible tries to make the change as atomic as possible (that is why it needs write to the dir) to make sure no other process reads the file in an inconsistent state.

That’s disappointing. I’m going to have to re-think my permission scheme. But thanks for the info.

JW

I’m running into this exact issue too. We thought we’d make permissions as tight as possible, but due to how atomic_move() works Ansible requires the parent directory to be writeable too.

Is there a best-practice workaround for this? Obviously one way is to just make the parent directory writeable, but without that? Is there a way to generate the template file locally and then copy it over in a non-atomic way so it just requires write permissions on that file? Similar to how you would be hand when editing the file with your favourite text editor?

-Ben

I suppose it could be made to check if the parent dir did not have permissions and in such case open the file, clear the contents, and write data back into it, but this seems a little gross to me.

In particular, copy operations on large files would require loading everything into memory, wouldn’t they?

Really this is the first time I’ve ever heard of this being a problem - not saying I’m not sympahethic - but it’s interesting it has not been a request yet.

I suppose it could be made to check if the parent dir did not have permissions and in such case open the file, clear the contents, and write data back into it, but this seems a little gross to me.

I think that would be “gross” if it weren’t explicit. What about an explicit nonatomic=yes or overwrite=yes option that enables this? The default would be no (the current behaviour), and the docs could say something like, “by default, Ansible does an atomic move and requires write permission on the file’s directory to allow it to create a temporary file; if this option is turned on, the copy is non-atomic and write permission on the directory in not required”.

In particular, copy operations on large files would require loading everything into memory, wouldn’t they?

I haven’t dived very deep on how atomic_move is implemented, but why would doing this change the memory requirements?

Really this is the first time I’ve ever heard of this being a problem - not saying I’m not sympahethic - but it’s interesting it has not been a request yet.

Two requests in two months on this mailing list. :wink:

Don’t worry, we’ll be working around this by slightly looser permissions in the meantime.

-Ben

Because you'd have to read in the source file to be able to 'cat' it
into the truncated
destination file, rather than just moving it into place
(which requires the directory to be updated, therefore writable).

Dick Davies <dick@hellooperator.net> napisał:

I find the concept of having to specify a parameter like nonatomic or overwrite a bit arcane for this, as it doesn’t really describe what is being done.

My gut feeling is the present behavior is acceptable, if the files were not there, ansible would need to create the file anyway, as is it’s nature.

if the files were not there, ansible would need to create the file anyway,
as is it's nature

That's a fair point. If ansible is being used for end-to-end server
configuration (as is often the case) it will have to create the file anyway.

However, one thing that could be improved here is the documentation --
mention in the "template" (and "copy"?) module docs that write access on
the directory is required and why (due to the atomic temp file/rename
magic).

-Ben

Or perhaps improve the error message when it fails, yes.

Agreed.

Ah yes – good point. For me the error message was the first point of contact, and I was confused by it. It said:

Destination /etc/nginx/conf.d not writable

And my thought (till I looked at the Ansible source) was “why does the directory need to be writable when I’m just copying the existing file /etc/nginx/conf.d/upstream.conf?” Perhaps change the error message to something like:

Destination’s parent directory %s not writable (must be writable for atomic file move)

-Ben

I’d actually like to see some general information in the documentation about this topic of user permissions. I would think that a lot of people get the idea to create users with limited sudo rights, and use them with Ansible. But there are cases like this where Ansible doesn’t allow that. It would be good to know that up front, so you can think about how you want to handle permissions. If the recommendation is that Ansible always be run as a user with full sudo rights, that should be stated somewhere.

Good point. We are in fact running our scripts as a user with limited sudo rights, so it’s good to know that’s not recommended practice.

That’s actually in the docs in the “note” section under http://docs.ansible.com/intro_adhoc.html#id8 where sudo is first introduced.

Then it sounds like the existing error message does indicate the directory needs to be writeable which may be good enough, I’m not sure whether most people would know or should need to know what “atomic move” was.