I want to recursively copy over a directory and render all .j2 files in there as templates. For this I am currently using the following lines:
- template: >
src=/src/conf.d/{{ item }}
dest=/dest/conf.d/{{ item|replace('.j2','') }}
with_lines: find /src/conf.d/ -type f -printf "%P\n"
Now I'm looking for a way to remove unmanaged files from this directory. For example if I remove a file/template from /src/conf.d/
I want Ansible to remove it from /dest/conf.d/
as well.
Is there some way to do this? I tried fiddling around with rsync --delete
, but there I got a problem with the templates which get their suffix .j2
removed.
I want to share my experience with this case.
Ansible from 2.2 is had with_filetree loop provides simple way to upload dirs, links, static files and even (!) templates. It's best way to keep my config dir synchronized.
Next we may want delete unused files from config dir. It's simple. We gather list of uploaded files and files exist on remote server, next remove diffrence.
But we may want to have unmanaged files in config dir. I've used
-prune
functionality offind
to avoid clearing folders with unmanaged files.PS _(Y)_ sure after I have deleted some unmanaged files
Usually I do not remove files but I add
-unmanaged
suffix to its name. Sample ansible tasks:EXPLANATION
Grep command uses:
-r
to do recursive search--include=\*.list
- only take files with .list extension during recursive search-L '^# Ansible'
- display file names that are not having line starting with '# Ansible'|| true
- this is used to ignore errors. Ansible'signore_errors
also works but before ignoring the error ansible will show it in red color during ansible-playbook run which is undesired (at least for me).Then I register output of grep command as a variable. When grep displays any output I set this task as changed (the line
changed_when
is responsible for this).In next task I iterate grep output (i.e. file names returned by grep) and run rename command to add suffix to each file.
That's all. Next time you run the command first task should be green and second skipped.
Apparently this isn't possible with ansible at the moment. I had a conversation with mdehaan on IRC and it boils down to ansible not having a directed acyclic graph for resources, making things like this very hard.
Asking mdehaan for an example e.g. authoritatively managing a sudoers.d directory he came up with these things:
I'd do it like this, assuming a variable defined as 'managed_files' up top that is a list.
We do this with our nginx files, since we want them to be in a special order, come from templates, but remove unmanaged ones this works:
The trick (as you can see) is that template and with_items have different attributes in the register results. Then you turn them into a list of files you manage and then get a list of the the directory and removed the ones not in that list.
Could be done with less code if you already have a list of files. But in this case I'm creating an indexed list so need to create the list as well with map.
Here's something I came up with:
Pros: You avoid multiple 'skipped' entries showing up during deletes.
Cons: You'll need to concatenate each template_results.results if you want to do multiple template tasks before doing the find/delete.