Ansible: How to recursively set directory and file permissions
file: dest=/foo/bar/somedir owner=root group=apache mode=u=rwX,g=rX,o=rX recurse=yes
will set directories to 755, and files to 644.
The Ansible file/copy modules don't give you the granularity of specifying permissions based on file type so you'd most likely need to do this manually by doing something along these lines:
- name: Ensure directories are 0755 command: find {{ path }} -type d -exec chmod 0755 {} \; - name: Ensure files are 0644 command: find {{ path }} -type f -exec chmod 0644 {} \;
These would have the effect of recursing through
{{ path }}
and changing the permissions of every file or directory to the specified permissions.
Source: https://stackoverflow.com/a/28782805/1306186
If you want to use the module file in ansible, you can:
file: dest=/foo/bar/somedir owner=root group=apache mode=0644 recurse=yes
file: dest=/foo/bar/somedir owner=root group=apache mode=0775
With this method you first set all the file (recurse=yes) to '644' and then you set /foo/bar/somedir to '775'.
This is not perfect because it will change your directory permission each time you play your playbook. But at least it is idempotent, not like the module command.
If you don't want to have 'changed' status, you can use the module stat. It will list all the files and directory in /foo/bar/somedir so you register the answer and then make a loop on those files only.
I'm not sure how much sense it would be to set directories to 0775 (rwxrwxr-x
) and files to 0644 (rw-r--r--
): group-writeable directories but not files?
If you meant to set files to 0664 (rw-rw-r--
) to ensure that files are not executable while directories are traversable then there is an elegant solution involving only one chmod
command:
chmod -c -R ug=rw,o=r,a-x+X "{{top_dir}}"
Here is how it can be used in Ansible:
- name: recursive chmod example
command: |
chmod -c -R ug=rw,o=r,a-x+X "{{item}}"
register: chmod_status
changed_when: chmod_status.stdout != ""
with_items:
- "/home/user/sample/dir"
chmod -c
prints all the changes that we can conveniently use to populate "changed" status in Ansible. I hope it make sense.
To only change mods when needed:
- name: make dirs 0755
command: find {{ your_path }} -type d ! -perm 0755 -exec chmod 0755 {} \;
- name: make files 0644
command: find {{ your_path }} -type f ! -perm 0644 -exec chmod 0644 {} \;