Paul Atkinson
Paul Atkinson

Reputation: 11

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.

Upvotes: 1

Views: 2448

Answers (2)

Bruce P
Bruce P

Reputation: 20759

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 

Upvotes: 1

Saravana Kumar
Saravana Kumar

Reputation: 836

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 

Upvotes: 1

Related Questions