how to make excluded variables dynamic in ansible - ansible

i am trying to make a playbook to change permissions across all servers, but i need to exclude few directories and files. I am trying to make the files allocation dynamic , as you can see i have excluded 2 , but i want to make it generalized or dynamic . plz suggest .
Below is my playbook, please note i am using directory structure :
permission.yml:
---
- hosts: 127.0.0.1
roles:
- { role: fileperm, target_dir: "/tmp/testingpermissions" }
- { role: fileperm, target_dir: "/tmp/abc" }
- { role: fileperm, target_dir: "/amp/app/tomcatdefault7055" }
Vars:
main.yml:
---
exclude1: "/tmp/testingpermissions/plugins"
exclude2: "/tmp/testingpermissions/files"
tasks:
main.yml:
---
- name: Ensure directories are 0755
command: find {{ target_dir }} -type d ! -path "{{ exclude1 }}*" ! -path "{{ exclude2 }}*" -exec chmod -c 0755 {} \;
register: chmod_result
changed_when: "chmod_result.stdout != \"\""

You could use the 'file' module, and loop through your list of directories that need to have their permissions changed,
e.g. sth like this in the vars:
# /vars/main.yml
updatepermissions:
- "/tmp/testingpermissions"
- "/tmp/abc"
- "/amp/app/tomcatdefault7055"
... and then sth like this in the tasks:
# /tasks/main.yml
- name: Set directory permissions to 0755
file:
path: "{{ item }}"
state: directory
mode: 0755
with_items: "{{ updatepermissions }}"
This will set the permissions on only the directories that you specify. So instead updating permissions for everything except for some excluded few, you'd only update the permissions on a set list of directories that need the given permissions.
For directories where you don't want to exclude any subdirectories from setting permissions, you can add "recurse=yes".
Otherwise, if you prefer the command task with "! -path", you could maybe do something like this:
# /vars/main.yml
updatepermissions:
- include: "/tmp/testingpermissions"
exclude: "! -path \"/tmp/testingpermissions/plugins\" ! -path \"/tmp/testingpermissions/abc\""
- include: "/some/other/directory"
exclude: ""
and then in the tasks sth like this:
# /tasks/main.yml
- name: update permissions
command: "find {{ item.include }} -type d {{ item.exclude }} -exec chmod -c 0755 {} \;"
register: chmod_result
changed_when: "chmod_result.stdout != \"\""
with_items: "{{ updatepermissions }}"

Related

Ansible recursively set permission on directory

I am trying to set permission on directories from a list.
Below is an example list where I would like dirA, dirB, dirC and dirD to get o-w permission.
"__cronjob_paths": [
"/dirA/dirB",
"/dirC/dirD",
]
file module has recursive option but it also sets the permissions on the files within the directories so it's not an option.
Would a regex or filter be the best way to solve this? Maybe filter out the /and save the directories into another list which i can loop through and set permissions?
I also need to have in mind that there could be other directories within the system that has a directory with the same name as the one from the list (which should not get o-w)
Create lists of the subdirs and indexes, e.g.
- set_fact:
_paths: "{{ _paths|d([]) + [{'dir': _dir, 'idx': _idx}] }}"
loop: "{{ __cronjob_paths }}"
vars:
_dir: "{{ item.split('/')|select() }}"
_idx: "{{ range(1, _dir|length + 1) }}"
gives
_paths:
- dir:
- dirA
- dirB
idx:
- 1
- 2
- dir:
- dirC
- dirD
idx:
- 1
- 2
Now, you can iterate idx subelements and join the subdirs, e.g.
- debug:
msg: "chmod o-w /{{ item.0.dir[:item.1]|join('/') }}"
with_subelements:
- "{{ _paths }}"
- idx
gives
msg: chmod o-w /dirA
msg: chmod o-w /dirA/dirB
msg: chmod o-w /dirC
msg: chmod o-w /dirC/dirD
Proceed either with command or file module if this is what you want.

What is the ansible equivalent to find -exec cp with file extensions filtered?

I need to replace this kind of command:
- name: Copy files .par
shell: find {{ path_src }}/* -name '*.ext' -exec cp {} {{ path_dest }} \; | find {{ path_src }}/ -type f -a ! -name "*.*" -exec cp {} {{ part_dest }} \;
ignore_errors: yes
The '.ext' can be different on the same task and it's linked to the destination if i find '.sql' i want it to go to the destination .sql
I try this kind of solution
- name: TEST COPY
hosts: localhost
tasks:
- name: Test Find
find:
paths: /home/me/test/find_cpy
file_type: file
recurse: yes
patterns: ['*.ext','*.sql','*.sh']
register: find_list
- name:
debug: var=find_list
- name: test set fact
set_fact:
path_file: "{{ find_list.files | map(attribute='path') | list }}"
register: test_fact
- debug: var=test_fact
- name: test sql copy
copy:
src: "{{ test_fact.path}}"
dest: "/home/me/test/test_copy/sql"
owner: me
mode: 0755
when: ????
- name: test register
copy:
src: "{{ item.path }}"
dest: "/home/me/test/test_copy/"
owner: me
mode: 0755
with_items: "{{ find_list.files }}"
The test register is ok but the test sql copy i have no idea.
Any Ideas
Thanks
Only few changes are needed
- name: TEST COPY
hosts: localhost
gather_facts: false
tasks:
- name: Test Find
find:
paths: /home/me/test/find_cpy
file_type: file
recurse: yes
patterns: ['*.ext','*.sql','*.sh']
register: find_list
- name:
debug: var=find_list
- name: test set fact
set_fact:
path_file: "{{ find_list.files | map(attribute='path') | list }}"
# register: test_fact
Registered variable test_fact is not needed. The list of the paths has been stored in path_file.
- debug: var=path_file
- name: test sql copy
copy:
# src: "{{ test_fact.path}}"
src: "{{ item }}"
dest: "/home/me/test/test_copy/sql"
owner: me
mode: 0755
loop: "{{ path_file }}"
Loop the list of paths path_file and copy items to the destination.
- name: test register
copy:
# src: "{{ item.path }}"
src: "{{ item }}"
dest: "/home/me/test/test_copy/"
owner: me
mode: 0755
# with_items: "{{ find_list.files }}"
loop: "{{ path_file }}"
Loop find_list.files and item.path gives the same results as path_file and item. I'm not sure what the purpose of this task should be.

running shall command with ansible

i am new to Ansible, and have write .yml file to empty a file, just like ">file_name"
---
tasks:
- name: Empty Log Files greater then 400M
shell: 'find "{{ item }}" -name "messages*" -size +400M -exec sh -c '> {}' \;'
with_items:
- /var/log
- /var/opt
- /var/spool/mail
ignore_errors: yes
and i am getting this following error
ERROR! Syntax Error while loading YAML.
The error appears to have been in
'/tmp/clean.yml': line 7, column 11, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
name: Delete Log Files greater then 400M
shell: 'find "{{ item }}" -name "messages*" -size +400M -exec sh -c '> {}' \;'
^ here We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression
brackets when they start a value. For instance:
with_items:
{{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
exception type: exception: mapping
values are not allowed in this context in "", line
7, column 11
where im getting it wrong?
Kindly refer below playbook as a reference for the same.
---
- name: play to check the file size
hosts: "{{ servers }}"
tasks:
- name: Recursively find /tmp files older than 4 weeks and equal or greater than 1 megabyte
find:
paths: "{{ item }}"
age: 4w
size: 1m
recurse: yes
with_items:
- path_1
- path_2
- path_3

for loop not working with ansible shell module

I am trying to check group ownership of all the directory named "deployments" inside path. To do this I am using for loop with find command and store all the deployments dir in variable. And then using grep I am checking whether there is any deviation. Below is my task. The problem is that the Its not working and even if group ownership is different its not detecting it.
How can i check and fix how the command i am passing in shell module is running correctly by shell module.
---
- name: deployment dir group ownership check
shell: for i in `find /{{ path }} -name deployments -type d -print`;do ls -ld $i | grep -v 'sag';done > /dev/null 2>&1; echo $?
register: find_result
delegate_to: "{{ pub_server }}"
changed_when: False
ignore_errors: true
tags:
- deployment_dir
- debug: var=find_result
- name: status of the group in deployments dir
shell: echo "Success:Deployments dir is owned by sag group in {{ path }} in server {{ pub_server }}" >> groupCheck.log
when: find_result.stdout == "1"
changed_when: False
tags:
- deployment_dir
- name: status of the group in deployments dir
shell: echo "Fail:Deployments dir is NOT owned by sag group in {{ path }} in server {{ pub_server }}" >> groupCheck.log
changed_when: False
when: find_result.stdout == "0"
tags:
- deployment_dir
Why you use that shell with find?
You can stat the folder and then get the UID and GID for set those permissions...
---
- hosts: localhost
gather_facts: no
connection: local
tasks:
- stat:
path: /tmp
register: tmp
- debug: msg="Uid {{ tmp.stat.uid }} - Guid {{ tmp.stat.gid }}"
Playbook run:
PLAY ***************************************************************************
TASK [stat] ********************************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Uid 0 - Guid 0"
}
Tmp folder:
14:17:17 kelson#local:/# ls -la /
drwxrwxrwt 23 root root 4096 Mai 14 14:17 tmp
Using that line of thinking, you can use the find module, register the output and use stat with your results to seek every folder permissions or set those you want...

Ansible - Multiple Loops - Directory Verification

Looking to create a list of directories for ansible to verify exist then check they are correctly defined and if not update them.
How can create multiple loops that work together?
# Determine if a path exists and is a directory.
- name: check directory existance and characteristics
stat: path=/path1
register: p1
# both that p.stat.isdir actually exists, and also that it's set to true.
- debug: msg="Path exists"
when: p1.stat.isdir is defined
- debug: msg="This is a directory"
when: p1.stat.isdir
- file: path=/path1 owner='user1' group='group1' mode=0755 state=directory
when: p1.stat.pw_name != 'user1' or p1.stat.gr_name != 'group1' or p1.stat.mode != '0755'
Ideally want to check all directories exist and update where they do then fail with list of those that don't.
Ultimately want something like file of directories and ownership settings to verify.
You can define a task.yml with below checks and then in a playbook execute the task with array of paths you need to run this task on.
----Task.yml
# Determine if a path exists and is a directory.
- name: check directory existance and characteristics
stat: path=/path1
register: p1
# both that p.stat.isdir actually exists, and also that it's set to true.
- debug: msg="Path exists"
when: p1.stat.isdir is defined
- debug: msg="This is a directory"
when: p1.stat.isdir
- file: path=/path1 owner='user1' group='group1' mode=0755 state=directory
when: p1.stat.pw_name != 'user1' or p1.stat.gr_name != 'group1' or p1.stat.mode != '0755'
playbook to run the task
--- Playbook
- name: Running Task
host: local
var:
- paths: ["path1" , "path2", "path3"]
tasks:
- include: task.yml path={{item}}
with_items: paths
Ideally want to check all directories exist and update where they do then fail with list of those that don't.
If that's the case then you're over-engineering things. All you need to do is invoke the file task with the appropriate parameters for each directory. Since Ansible is idempotent it will check the parameters for you and only change those which need to be changed. So something like this should be all you need:
- name: directories
file: path={{ item.p }}
state=directory
owner={{ item.o }}
group={{ item.g }}
mode=0755
with_items:
- { p: '/deploy', o: 'deploy_user', g: 'deploy_group' }
- { p: '/deploy/scripts', o: 'deploy_user', g: 'deploy_group' }
- { p: '/deploy/lib', o: 'deploy_user', g: 'deploy_group' }
The first time this task is run it will create the directories /deploy, /deploy/scripts, and /deploy/lib with the specified ownership & groups. The second time this task is run it should do nothing since those paths will already exist with the specified ownership & groups. Ansible will format the output nicely, especially if it's running in a shell with color enabled, so it will be easy to just read the output of this one task to determine what was changed and what wasn't.
Edit: If you want to test & display errors if directories don't exist then a simple two step approach should also work:
vars:
my_dirs:
- { p: '/deploy', o: 'deploy_user', g: 'deploy_group' }
- { p: '/deploy/scripts', o: 'deploy_user', g: 'deploy_group' }
- { p: '/deploy/lib', o: 'deploy_user', g: 'deploy_group' }
tasks:
- name: Check directories
stat: path={{ item.p }}
register: st
with_items: my_dirs
- name: Complain
debug: "Path {{ item.p }} does not exist or isn't set properly"
when: p1.stat.isdir is not defined or not p1.stat.isdir or p1.stat.pw_name != item.o or ...
with_items: my_dirs
- name: create directories
file: path={{ item.p }}
state=directory
owner={{ item.o }}
group={{ item.g }}
mode=0755
with_items: my_dirs

Resources