In this article I will demonstrate how we can perform different file operations with Ansible.
Ansible copy
module - copying files over remote machines
In one single playbook I will include all possible use cases for copying files over remote nodes.
---
- hosts: worker1
become: yes
gather_facts: false
tasks:
- name: Task1 - copy file from local machine to remote server
copy:
src: /home/ansible_user/ansible/file_ops/file-normal.txt
dest: /home/ansible_user
- name: Task2 - copy file from local machine to remote server along with ownership and permissions
copy:
src: /home/ansible_user/ansible/file_ops/file-owner-perms.txt
dest: /home/ansible_user/
owner: ansible_user
group: ansible_user
mode: '0777'
- name: Task3 - copy directory from local machine to remote server
copy:
src: /home/ansible_user/ansible/file_ops/dir1
dest: /home/ansible_user
owner: ansible_user
group: ansible_user
mode: '0755'
- name: Task4 - copy multiple files from local machine to remote server
copy:
src: /home/ansible_user/ansible/file_ops/dir2
dest: /home/ansible_user
owner: ansible_user
group: ansible_user
mode: '0755'
with_items:
- file-multi1.txt
- file-multi2.txt
- name: Task5 - copy file from local machine to remote server along with backup option
copy:
src: /home/ansible_user/ansible/file_ops/file-backup.txt
dest: /home/ansible_user/
owner: ansible_user
group: ansible_user
mode: '0755'
backup: yes
- name: Task6 - copy file from local machine to remote server along with content option
copy:
content: "Welcome to LearnCodeOnline"
dest: /home/ansible_user/file-content.txt
owner: ansible_user
group: ansible_user
mode: '0755'
- name: Task7 - copy file from local machine to remote server along with force option
copy:
src: /home/ansible_user/ansible/file_ops/file-force.txt
dest: /home/ansible_user/file-force.txt
owner: ansible_user
group: ansible_user
mode: '0755'
force: no
Let us understand all the tasks one by one.
- Task1 will simply copy
file-normal.txt
from local machine to worker1 - Task2 will copy
file-owner-perms.txt
with the ownership and permissions I've mentioned in the play i.e. ownership -ansible_user
and permissions as0777
- Task3 will copy
dir1
directory from local machine to worker1
For copying directories, you have two options. If you put a / after the directory name in
src
, then it will copy anything inside that directory to the destination folder. If you don’t put the / insrc
, then it will first create the directory at the destination and then copy everything inside.
- Task4 is used when we don't want to copy the entire directory to remote machine, instead just to copy few files.
- Task5 will create a backup file including the timestamp information when someone changes the source file. (You can try changing content of file-backup.txt file run the playbook again.)
- Task6 is used when you want to copy a file from local machine to remote server along with the customized content in it.
- Task7 will be used when we don't want to overwrite the file. The default is yes, which will replace the remote file when contents are different than the source. If no, the file will only be transferred if the destination does not exist.
Here is the list of files/directories on our local machine which we wants to copy over.
file_ops $ tree
.
├── copy.yml
├── dir1
│ ├── abc
│ └── test
├── dir2
│ ├── file-multi1.txt
│ └── file-multi2.txt
├── dir_copy.yml
├── file-backup.txt
├── file-content.txt
├── file-force.txt
├── file-normal.txt
├── file-owner-perms.txt
└── myinventory
2 directories, 12 files
Let us execute the playbook.
Now verify the results on the remote system one by one task.
As I have mentioned above to test the backup option you need to change the content of file-backup.txt file and run the playbook again. You will see a backup file created on the remote system with old content.
For more details on copy
module follow official docs .
Ansible lineinfile
module – Manage lines in text files
We use this module when we want to insert a line in file or replace an existing line using a back-referenced regular expression.
Not recommended if you want to change multiple lines or block.
lineinfile
example 1 - Modifying a line
Here is our playbook which will go and change a setting in a file.
---
- hosts: worker1
become: yes
gather_facts: false
tasks:
- name: Ensure SELinux is set to enforcing mode
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=enforcing
Let us run the playbook.
file_ops $ ansible-playbook -i myinventory lineinfile.yml
Verify the changes on worker1 node.
file_ops $ ansible -i myinventory worker1 -m shell -a "cat /etc/selinux/config | grep enforcing"
worker1 | CHANGED | rc=0 >>
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
SELINUX=enforcing
lineinfile
example 2 - Checking existence of a string in a file and add the line after it
---
- name: Testing lineinfile module
hosts: worker1
become: yes
tasks:
- name: "Check existence of a String in a file and add the line after it"
lineinfile:
path: /home/ansible_user/lineinfile_test_file1.txt
insertafter: "ExampleName"
line: "lineinfile_insert_test"
firstmatch: yes
state: present
create: yes
backup: yes
Here we are adding a line containing string ‘lineinfile_insert_test’ after the line that matches ‘ExampleName’. Similarly the option ‘insertbefore’ can be used to add the line before the specific line if the match is found.
create
option will create the file if doesn't exists already.
Let's run the playbook.
Verify the outcome:
file_ops $ ansible -i myinventory worker1 -m shell -a "cat /home/ansible_user/lineinfile_test_file1.txt"
worker1 | CHANGED | rc=0 >>
ExampleName
lineinfile_insert_test
Please go through the official docs to get more idea about other options.
Ansible replace
module – Replace all instances of a particular string
This module is used when we want to replace all instances of a pattern within a file.
Lets understand this by our example playbook.
---
- name: Testing lineinfile module
hosts: worker1
become: yes
tasks:
- name: check the content of file before replace operation
shell: 'cat /home/ansible_user/replace_example.txt'
register: var_output_1
- name: check the content of file before replace operation
debug:
var: var_output_1.stdout_lines
- name: "Check existence of a String in a file and add the line after it"
replace:
path: /home/ansible_user/replace_example.txt
regexp: "Hello Learners"
replace: "Hello LearnCodeOnline"
backup: yes
- name: check the content of file after replace operation
shell: 'cat /home/ansible_user/replace_example.txt'
register: var_output_2
- name: check the content of file after replace operation
debug:
var: var_output_2.stdout_lines
In this example we are replacing every occurrence of Hello Learners
in /home/ansible_user/replace_example.txt
file on worker1 node and displaying the content of that file before and after the replace operation.
Let us execute the playbook.
file_ops $ ansible-playbook -i myinventory replace.yml
That's all for this article.
I have covered here the most important and frequently used File Operations modules but yes there are many others available which you can go through one by one and try implementing them.
Ref: docs.ansible.com/ansible/2.9/modules/list_o..
Hope you like the article. Stay Tuned for more.
Thank you. Happy learning!