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:
mkdir ~ /project |
Next, create an inventory file inside the ~/project directory:
nano ~ /project/inventory .txt |
Add the following lines:
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:
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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:
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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:
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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.
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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.
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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.
nano ~ /project/playbook .yml |
Add the following lines:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |
You should get the following output:
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:
- 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:
- 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:
cd ~ /project ansible-playbook playbook.yml -i inventory.txt |