How to Create a Directory in Ansible

You will need to create directories or folders in Ansible many times during may of the DevOps process. Although you could do create directories using shell or command module, ansible provides a better and safer method for creating directories using the ‘file’ module.

Ansible Directory Creation example

To create a directory using the file module, you need to set two parameters.

  • Path(alias – name, dest) – This is the absolute path of the directory.
  • State – You should give this as ‘directory.’ By default, the value is ‘file.’

For example, I need to create a directory ‘devops_directory’ in the path /tmp.

- hosts: all
  tasks:
  - name: ansible create directory example
    file:
      path: /tmp/devops_directory
      state: directory

output
======
mdtutorials2@system01:~$ ls -lrt /tmp
drwxr-xr-x 2 root root 4096 Oct 4 07:19 devops_directory

If I execute the task again, since the directory is already present, nothing will be changed.

Changing the Permissions for a Directory in Ansible

In the above task, the directory will be created with the default permission. We can set the permissions using the ‘mode’ parameter. We can give it in two ways.

  • the symbolic form like ‘u=rw,g=rw,o=rw’ -> This gives read and write permission to everyone.
  • Octal numbers  like ‘0777’ -> Read, write and execute permission to everyone

The following task sets the permission of already created devops_directory to ‘u=rw,g=wx,o=rwx.’

- hosts: all
  tasks:
  - name: ansible create directory with mode setting example
    file:
      path: /tmp/devops_directory
      state: directory
      mode: "u=rw,g=wx,o=rwx"

output
======
mdtutorials2@system01:~$ ls -lrt /tmp
drw--wxrwx 2 root          root          4096 Oct  4 07:19 devops_directory

mdtutorials2@system01:~$ touch /tmp/devops_directory/test1
mdtutorials2@system01:~$ ls -lrt /tmp/devops_directory/test1
-rw-rw-r-- 1 mdtutorials2 mdtutorials2 0 Oct  4 09:35 /tmp/devops_directory/test1

You can see the permissions of the devops_directory has changed as given on the task.

But the files created inside that folder has the default permissions set.

Changing the Permissions for Directory and the files

You can modify the permissions of a directory and all the files inside also recursively. You can use the above task itself. You just have to add the recurse parameter and set it to ‘yes.’

output
======
mdtutorials2@system01:~$ touch /tmp/devops_directory/test2
mdtutorials2@system01:~$ ls -lrt /tmp/devops_directory/test2
-rw-rw-r-- 1 root root 0 Oct  4 09:44 /tmp/devops_directory/test2


- hosts: all
  tasks:
  - name: ansible set permission recursvely for a directory
    file:
      path: /tmp/devops_directory
      state: directory
      mode: "u=rw,g=wx,o=rwx"
      recurse: yes

output
======
mdtutorials2@system01:~$ ls -lrt /tmp/devops_directory/test2
-rw--wxrwx 1 root root 0 Oct  4 09:48 /tmp/devops_directory/test2

Create multiple directories using with_items

You can also create multiple directories using the with_items statement in Ansible.

For example, to create three directories, devops_system1, devops_system2, and devops_system3, you can execute the following task

- hosts: all
  tasks:
  - name: ansible create multiple directory example
    file:
      path: "{{ item }}"
      state: directory
    with_items:
      - '/tmp/devops_system1'
      - '/tmp/devops_system2'
      - '/tmp/devops_system3'

output
======
mdtutorials2@system01:~$ ls -lrt /tmp
total 16
drwxr-xr-x 2 root          root          4096 Oct  4 09:59 devops_system1
drwxr-xr-x 2 root          root          4096 Oct  4 09:59 devops_system2
drwxr-xr-x 2 root          root          4096 Oct  4 09:59 devops_system3

But what if you need to set the permission differently for each directory while using with_items.
In the following task, I am independently setting the modes for each directory.

- hosts: all
  tasks:
  - name: ansible create directory with_items example
    file:
      path: "{{ item.dest }}"
      mode: "{{item.mode}}"
      state: directory
    with_items:
      - { dest: '/tmp/devops_system1', mode: '0777'}
      - { dest: '/tmp/devops_system2', mode: '0707'}
      - { dest: '/tmp/devops_system3', mode: '0575'}

output
======
mdtutorials2@system01:~$ ls -lrt /tmp/
total 16
drwxrwxrwx 2 root          root          4096 Oct  4 09:59 devops_system1
drwx---rwx 2 root          root          4096 Oct  4 09:59 devops_system2
dr-xrwxr-x 2 root          root          4096 Oct  4 09:59 devops_system3

Creating a local directory using local_action statement

You can also create a local directory in ansible using the ‘local_action’ statement along with the given examples.

For example, to create a directory ‘local_folder’ in the Ansible control machine.

- hosts: all
  tasks:
  - name: ansible create local directory example
    local_action:
      module: file
      path: /tmp/local_file
      state: directory 

Creating a directory with timestamp

There are scenarios when you need to attach a timestamp also with the directory name. You can use the ansible date fact for such scenarios. For more information on how to use the date fact in ansible refer to this post.

The following task will append the date also with the directory name.

- hosts: all
  tasks:
  - name: ansible set permission recursvely for a directory
    file:
      path: "/tmp/devops_directory{{ansible_date_time.date}}"
      state: directory
      mode: "u=rw,g=wx,o=rwx"
      recurse: yes

output
======
mdtutorials2@system01:~$ ls -lrt /tmp

drw--wxrwx 2 root root 4096 Oct 4 10:56 devops_directory2017-10-04

Deleting a Directory in Ansible

You can delete a directory by setting the state parameter to absent. This will remove the directory and all its contents.

For example, to remove the ‘/tmp/devops/’ directory, you can execute the following task.

mdtutorials2@system01:~$ ls -lrt /tmp/devops_directory/
total 0
-rw--wxrwx 1 mdtutorials2 mdtutorials2 0 Oct  4 09:35 test1
-rw--wxrwx 1 mdtutorials2 mdtutorials2 0 Oct  4 09:48 test2


- hosts: all
  tasks:
  - name: ansible remove directory example
    file:
      path: /tmp/devops_directory
      state: absent

output
======
mdtutorials2@system01:~$ ls -lrt /tmp/devops_directory/
ls: cannot access '/tmp/devops_directory/': No such file or directory