Ansible file Module – Tutorial and Examples

ansible file module

Ansible file module is used to deal with the files, directories, and symlinks. You can create or remove files, symlinks or directories on the remote hosts using the Ansible file module. It is also used to change the file ownership, group and permissions.

Ansible file module performs all tasks on the remote hosts. So before changing the ownership and permissions of the files and directories, relevant user and group must exist on the remote hosts. Otherwise, playbook execution will fail. In this case, you should always check the user or group’s existence on the remote hosts then change the ownership or permissions.

In this tutorial, we will explain how to use Ansible file module to create files and directories on the remote hosts.

Prerequisites

  • One Ansible control node: A server running CentOS 8 with Ansible installed and configured. To set up Ansible, please follow my guide on How to Install and Setup Ansible
  • One Ansible Target node: A fresh server running CentOS 8.

Create an Inventory File

For the purpose of this tutorial, you will need to create a project directory and an inventory file on the Ansible host system.

First, create a new project directory with the following command:

1
mkdir ~/project

Next, create an inventory file inside the ~/project directory:

1
nano ~/project/inventory.txt

Add the following lines:

1
target1 ansible_host=192.168.0.11 ansible_user=root ansible_ssh_pass=admin@123

Save and close the file when you are finished.

Create an Empty File with File Module

The simple and easiest way to create an empty file on the remote hosts is to use Ansible file module.

The following example will create an empty file named myfile.txt inside /opt directory on the remote hosts.

Create a playbook.yml file inside the ~/project directory:

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
- hosts: all
 
  tasks:
  - name : Create an Empty File
    file: path=/opt/myfile.txt state=touch

Save and close the file when you are finished.

Where:

  • hosts : Defines a single or group of hosts from the Ansible inventory file.
  • tasks : Declares that remote hosts want to perform a task.
  • name : Defines a name of the task you want to perform.
  • file : Name of the module used to perform the task.
  • path : Defines the path on the remote hosts where you want to create a file.
  • state : Run touch command to create an empty file.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create an Empty File] *******************************************************************************************************************
changed: [target1]
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

There are two options for dealing with files when using Ansible file module: state=touch and state=file. The state=file option will ensure a path is a file. You will get an error if the path does not exist or if the path is not a file.

To understand it better, let’s create a playbook to check the file existence in the path /opt/yourfile.txt:

Create a playbook.yml file inside the ~/project directory:

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
- hosts: all
 
  tasks:
  - name : Create an Empty File
    file: path=/opt/yourfile.txt state=file

Save and close the file when you are finished.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create an Empty File] *******************************************************************************************************************
fatal: [target1]: FAILED! => {"changed": false, "msg": "file (/opt/yourfile.txt) is absent, cannot continue", "path": "/opt/yourfile.txt", "state": "absent"}
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  

Create a File With Content

Using the above method, you can create only empty file on the remote hosts. If you want to create a file and add some content then you can use the copy module and include the content parameter to add the content to your file.

The following example will create an empty file named myfile.txt inside /opt directory and add two lines to the file on the remote hosts.

Create a playbook.yml file inside the ~/project directory:

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
6
7
8
9
- hosts: all
 
  tasks:
  - name : Create a File with Content
    copy:
        dest: /opt/myfile.txt
        content: |
          This is first line
          This is second line

Where:

  • copy : Defines the Ansible copy module.
  • dest : Defines the path of the file on the remote hosts.
  • content : This will add the content to the specified file.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create a File with Content] *************************************************************************************************************
changed: [target1]
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Create Multiple File with File Module

Ansible file module will also help you to create multiple files and directories on the remote hosts. In some cases, you will need to create multiple files on the remote hosts. In that case, you can use a loop and combine all files in a single task.

Let’s create a playbook to create multiple files named file1.txt, file2.txt, file3.txt and file4.txt on the remote hosts.

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
6
- hosts: all
 
  tasks:
  - name: Create Multiple Files
    file: path={{"/opt/"}} state=touch
    loop: [file1.txt, file2.txt, file3.txt, file4.txt]

Save and close the file when you are finished.

Where:

  • path : Defines the path of the remote hosts.
  • loop : Defines a list of files that you want to create on the remote hosts.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
11
12
13
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create Multiple Files] ******************************************************************************************************************
changed: [target1] => (item=file1.txt)
changed: [target1] => (item=file2.txt)
changed: [target1] => (item=file3.txt)
changed: [target1] => (item=file4.txt)
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Create a Directory with File Module

You can use Ansible file module to ensure a directory exists by setting the state parameter to the directory. If the directory already exists then Ansible will do nothing otherwise it will create a directory in the specified path.

Let’s create a playbook to create a directory named dir1 on the remote hosts.

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
- hosts: all
 
  tasks:
  - name: Create a Directory
    file: path="/opt/dir1" state=directory

Save and close the file when you are finished.

Where:

  • path : Defines the directory path on the remote hosts.
  • state=directory : Ensure a directory exists. If not exists then create a directory.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create a Directory] ***************************************************************************************************************
changed: [target1]
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Remove Files and Directories with File Module

You can use Ansible file module to remove files and directories by setting the state parameter to absent.

Let’s create a playbook to remove a directory named dir1 on the remote hosts. If the file is already removed playbook does nothing.

1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
- hosts: all
 
  tasks:
  - name: Delete a Directory
    file: path="/opt/dir1" state=absent

Save and close the file when you are finished.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Delete a Directory] ***************************************************************************************************************
changed: [target1]
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Setup Ownership and Permissions with File Module

You can use Ansible file module with owner, group and mode parameters to manage the ownership and permissions of files and directory.

Let’s create a playbook to set the ownership and permissions recursively and capture the output using the following details.

  • Ownership = user: ansible_user and group: ansible_user
  • Permissions = 744 Directory
  • Path = /opt/mydir
1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
6
7
- hosts: all
 
  tasks:
  - name: Change Wwnership & Permissions of a Directory
    file: path=/opt/mydir state=directory owner="{{ ansible_user }}" group="{{ ansible_user }}" mode=744 recurse=true
    register: file_output
  - debug: var=file_output

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Change Wwnership & Permissions of a Directory] ******************************************************************************************
changed: [target1]
 
TASK [debug] **********************************************************************************************************************************
ok: [target1] => {
    "file_output": {
        "changed": true,
        "diff": {
            "after": {
                "mode": "0744",
                "path": "/opt/mydir"
            },
            "before": {
                "mode": "0755",
                "path": "/opt/mydir"
            }
        },
        "failed": false,
        "gid": 0,
        "group": "root",
        "mode": "0744",
        "owner": "root",
        "path": "/opt/mydir",
        "size": 22,
        "state": "directory",
        "uid": 0
    }
}
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

If you want to set a different owner like www-data then you will need to use the option become=true as shown below:

1
2
3
4
5
6
7
- hosts: all
 
  tasks:
  - name: Change Ownership & Permissions of a Directory
    file: path=/opt/mydir state=directory owner="www-data" group="www-data" mode=744 recurse=true become=true
    register: file_output
  - debug: var=file_output

Create a Symlink with File Module

You can use Ansible file module to create a symlink by setting the state parameter to link. You will also need to set the src and dest parameters to set the path.

Let’s create a playbook and create a symlink using the following details.

  • Source : /etc/apache2/sites-available/wordpress.conf
  • Destination : /etc/apache2/sites-enabled/wordpress.conf
1
nano ~/project/playbook.yml

Add the following lines:

1
2
3
4
5
6
7
- hosts: all
 
  tasks:
  - name: Create a Symlink
    file: src=/etc/apache2/sites-available/wordpress.conf dest=/etc/apache2/sites-enabled/wordpress.conf state=link
    register: file_output
  - debug: var=file_output

Save and close the file when you are finished.

Next, change the directory to the ~/project and run the Ansible playbook with the following command:

1
2
cd ~/project
ansible-playbook playbook.yml -i inventory.txt

You should get the following output:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
PLAY [all] ************************************************************************************************************************************
 
TASK [Gathering Facts] ************************************************************************************************************************
ok: [target1]
 
TASK [Create a Symlink] ***********************************************************************************************************************
changed: [target1]
 
TASK [debug] **********************************************************************************************************************************
ok: [target1] => {
    "file_output": {
        "changed": true,
        "dest": "/etc/apache2/sites-enabled/wordpress.conf",
        "diff": {
            "after": {
                "path": "/etc/apache2/sites-enabled/wordpress.conf",
                "state": "link"
            },
            "before": {
                "path": "/etc/apache2/sites-enabled/wordpress.conf",
                "state": "absent"
            }
        },
        "failed": false,
        "gid": 0,
        "group": "root",
        "mode": "0777",
        "owner": "root",
        "size": 43,
        "src": "/etc/apache2/sites-available/wordpress.conf",
        "state": "link",
        "uid": 0
    }
}
 
PLAY RECAP ************************************************************************************************************************************
target1                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
You should also read the following articles

About Hitesh Jethva

I am Hitesh Jethva Founder and Author at LinuxBuz.com. I felt in love with Linux when i was started to learn Linux. I am a fan of open source technology and have more than 15+ years of experience in Linux and Open Source technologies.

View all posts by Hitesh Jethva