PL - 010 — Ansible Practice: Error Handling, File Management & Remote File Operations
Error Handling in Automation
[cnode@control-node ~]$ ./validate_nodes.sh
----- dev1 -----
dev1
root
----- dev2 -----
dev2
root
----- testserver -----
testserver
root
----- prodserver -----
prodserver
root
[cnode@control-node ~]$ cd ansible-lab/
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory
[cnode@control-node ansible-lab]$
[cnode@testserver ~]$ ls
[cnode@testserver ~]$ rpm -q httpd nginx mariadb-server php
package httpd is not installed
package nginx is not installed
mariadb-server-10.11.18-1.el10.x86_64
package php is not installed
[cnode@testserver ~]$ sudo rpm -e --nodeps mariadb-server
Removed '/etc/systemd/system/multi-user.target.wants/mariadb.service'.
Removed '/etc/systemd/system/mysql.service'.
Removed '/etc/systemd/system/mysqld.service'.
[cnode@testserver ~]$ rpm -q httpd nginx mariadb-server php
package httpd is not installed
package nginx is not installed
package mariadb-server is not installed
package php is not installed
[cnode@testserver ~]$
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory
[cnode@control-node ansible-lab]$ vi playbook_handle-error.yml
[cnode@control-node ansible-lab]$ vim playbook_handle-error.yml
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory playbook_handle-error.yml
[cnode@control-node ansible-lab]$ cat playbook_handle-error.yml
---
# Installing different packages
- name: Play handling errors
hosts: test
become: true
tasks:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: htpd
state: latest
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
- name: Install the latest version of PHP
ansible.builtin.dnf:
name: php
state: latest
- name: Install the latest version of Samba
ansible.builtin.dnf:
name: samba
state: latest
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check playbook_handle-error.yml
playbook: playbook_handle-error.yml
[cnode@control-node ansible-lab]$ ansible-playbook playbook_handle-error.yml
PLAY [Play handling errors] *********************************************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
fatal: [testserver]: FAILED! => {"changed": false, "failures": ["No package htpd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
PLAY RECAP **************************************************************************
testserver : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
# If first tasks fails, remaining other automatically fails because ansible runs sequentially, thus
using errors handling concepts, where previous errors don't depend on successive tasks.
# To ignore error and proceed the next module
# The preceeding module should not depend on the previous module
# For example: web deployment depends on web server existance/installation
[cnode@control-node ansible-lab]$ vim playbook_handle-error.yml
[cnode@control-node ansible-lab]$ cat playbook_handle-error.yml
---
# Installing different packages
- name: Play handling errors
hosts: test
become: true
tasks:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: htpd
state: latest
ignore_errors: yes
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
ignore_errors: yes
- name: Install the latest version of PHP
ansible.builtin.dnf:
name: php
state: latest
ignore_errors: yes
- name: Install the latest version of Samba
ansible.builtin.dnf:
name: samba
state: latest
ignore_errors: yes
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check playbook_handle-error.yml
playbook: playbook_handle-error.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check playbook_handle-error.yml
PLAY [Play handling errors] *********************************************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
fatal: [testserver]: FAILED! => {"changed": false, "failures": ["No package htpd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring
TASK [Install the latest version of MariaDB] ****************************************
changed: [testserver]
TASK [Install the latest version of PHP] ********************************************
changed: [testserver]
TASK [Install the latest version of Samba] ******************************************
changed: [testserver]
PLAY RECAP **************************************************************************
testserver : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
[cnode@control-node ansible-lab]$
# errors are ignored and next tasks are performed successfully.
# But, actually in this case, httpd gets installed as it depends on mariadb-server
# NOTE: don't use the similar packages for same purpose
# For example: if using httpd don't use NGINX, there will be port conflict.
---
[cnode@control-node ansible-lab]$ cat playbook_handle-error-2.yml
---
# Installing different packages
- name: Play handling errors
hosts: test
become: true
tasks:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: httpd
state: latest
register: httpd_out
ignore_errors: yes
- name: Install the latest version of Nginx
ansible.builtin.dnf:
name: nginx
state: latest
when: "http_out.rc == 1"
ignore_errors: yes
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
ignore_errors: yes
- name: Install the latest version of PHP
ansible.builtin.dnf:
name: php
state: latest
ignore_errors: yes
- name: Install the latest version of Samba
ansible.builtin.dnf:
name: samba
state: latest
ignore_errors: yes
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ cp playbook_handle-error.yml playbook_handle-error-2.yml
[cnode@control-node ansible-lab]$ vim playbook_handle-error-2.yml
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check playbook_handle-error-2.yml
playbook: playbook_handle-error-2.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check playbook_handle-error-2.yml
PLAY [Play handling errors] *********************************************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
changed: [testserver]
TASK [Install the latest version of Nginx] ******************************************
fatal: [testserver]: FAILED! => {"msg": "The conditional check 'http_out.rc == 1' failed. The error was: error while evaluating conditional (http_out.rc == 1): 'http_out' is undefined. 'http_out' is undefined\n\nThe error appears to be in '/home/cnode/ansible-lab/playbook_handle-error-2.yml': line 21, column 13, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n state: latest\n when: \"http_out.rc == 1\"\n ^ here\n"}
...ignoring
TASK [Install the latest version of MariaDB] ****************************************
changed: [testserver]
TASK [Install the latest version of PHP] ********************************************
changed: [testserver]
TASK [Install the latest version of Samba] ******************************************
changed: [testserver]
PLAY RECAP **************************************************************************
testserver : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
[cnode@control-node ansible-lab]$
# But
[cnode@control-node ansible-lab]$ vim playbook_handle-error-2.yml
[cnode@control-node ansible-lab]$ cat playbook_handle-error-2.yml
---
# Installing different packages
- name: Play handling errors
hosts: test
become: true
tasks:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: htpd
state: latest
register: httpd_out
ignore_errors: yes
- name: Install the latest version of Nginx
ansible.builtin.dnf:
name: nginx
state: latest
when: "http_out.rc == 1"
ignore_errors: yes
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
ignore_errors: yes
- name: Install the latest version of PHP
ansible.builtin.dnf:
name: php
state: latest
ignore_errors: yes
- name: Install the latest version of Samba
ansible.builtin.dnf:
name: samba
state: latest
ignore_errors: yes
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check playbook_handle-error-2.yml
playbook: playbook_handle-error-2.yml
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ansible-playbook --check playbook_handle-error-2.yml
PLAY [Play handling errors] *********************************************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
fatal: [testserver]: FAILED! => {"changed": false, "failures": ["No package htpd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
...ignoring
TASK [Install the latest version of Nginx] ******************************************
fatal: [testserver]: FAILED! => {"msg": "The conditional check 'http_out.rc == 1' failed. The error was: error while evaluating conditional (http_out.rc == 1): 'http_out' is undefined. 'http_out' is undefined\n\nThe error appears to be in '/home/cnode/ansible-lab/playbook_handle-error-2.yml': line 21, column 13, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n state: latest\n when: \"http_out.rc == 1\"\n ^ here\n"}
...ignoring
TASK [Install the latest version of MariaDB] ****************************************
changed: [testserver]
TASK [Install the latest version of PHP] ********************************************
changed: [testserver]
TASK [Install the latest version of Samba] ******************************************
changed: [testserver]
PLAY RECAP **************************************************************************
testserver : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2
[cnode@control-node ansible-lab]$
Ansible block, rescue and always
Ansible provides block, rescue, and always to organize tasks and handle errors in a controlled way.
How It Works
- block — Contains the main tasks that Ansible attempts to execute.
- rescue — Runs only when a task inside the block fails.
- always — Runs regardless of whether the block succeeds or the rescue section runs.
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory playbook_handle-error-2.yml playbook_handle-error.yml
[cnode@control-node ansible-lab]$ cp playbook_handle-error-2.yml playbook_handle-error-3.yml
[cnode@control-node ansible-lab]$ ls
ansible.cfg playbook_handle-error-2.yml playbook_handle-error.yml
inventory playbook_handle-error-3.yml
[cnode@control-node ansible-lab]$ vim playbook_handle-error-3.yml
[cnode@control-node ansible-lab]$ cat playbook_handle-error-3.yml
---
# Handling errors using Block-Rescue-Always
- name: Handle errors using block, rescue, and always
hosts: test
become: true
tasks:
- name: Install Apache or fall back to Nginx
block:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: httpd
state: latest
rescue:
- name: Install the latest version of Nginx if Apache installation fails
ansible.builtin.dnf:
name: nginx
state: latest
always:
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check playbook_handle-error-3.yml
playbook: playbook_handle-error-3.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check playbook_handle-error-3.yml
PLAY [Handle errors using block, rescue, and always] ********************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
changed: [testserver]
TASK [Install the latest version of MariaDB] ****************************************
changed: [testserver]
PLAY RECAP **************************************************************************
testserver : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ vim playbook_handle-error-3.yml
[cnode@control-node ansible-lab]$ cat playbook_handle-error-3.yml
---
# Handling errors using Block-Rescue-Always
- name: Handle errors using block, rescue, and always
hosts: test
become: true
tasks:
- name: Install Apache or fall back to Nginx
block:
- name: Install the latest version of Apache
ansible.builtin.dnf:
name: htpd
state: latest
rescue:
- name: Install the latest version of Nginx if Apache installation fails
ansible.builtin.dnf:
name: nginx
state: latest
always:
- name: Install the latest version of MariaDB
ansible.builtin.dnf:
name: mariadb-server
state: latest
[cnode@control-node ansible-lab]$ ansible-playbook --check playbook_handle-error-3.yml
PLAY [Handle errors using block, rescue, and always] ********************************
TASK [Gathering Facts] **************************************************************
ok: [testserver]
TASK [Install the latest version of Apache] *****************************************
fatal: [testserver]: FAILED! => {"changed": false, "failures": ["No package htpd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
TASK [Install the latest version of Nginx if Apache installation fails] *************
changed: [testserver]
TASK [Install the latest version of MariaDB] ****************************************
changed: [testserver]
PLAY RECAP **************************************************************************
testserver : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
[cnode@control-node ansible-lab]$
### File Transfers | File Deployment & Dynamic Configuration Management
# 'file' module
--> any operations: vi, touch, mkdir, rm, ln, chmod, chown, SELinux, ... etc operations can be done using file mode
[cnode@control-node ansible-lab]$ ansible-doc file
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory
[cnode@control-node ansible-lab]$ vi file_operation_playbook.yml
[cnode@control-node ansible-lab]$ vim file_operation_playbook.yml
[cnode@control-node ansible-lab]$ cat file_operation_playbook.yml
---
# file operations
- name: play to create a playbook
hosts: develop
tasks:
- name: Create an empty file
ansible.builtin.file:
path: /home/cnode/devinfo
state: touch
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check file_operation_playbook.yml
playbook: file_operation_playbook.yml
[cnode@control-node ansible-lab]$ ansible-playbook file_operation_playbook.yml
PLAY [play to create a playbook] ****************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Create an empty file] *********************************************************
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
devinfo
[cnode@dev1 ~]$ ls -l /home/cnode/devinfo
-rw-r--r--. 1 root root 0 Sep 14 06:33 /home/cnode/devinfo
[cnode@dev1 ~]$
[cnode@dev1 ~]$ whoami
cnode
[cnode@dev1 ~]$
# But, owner is root and group is root. As, ( become = true )
[cnode@control-node ansible-lab]$ vim file_operation_playbook.yml
[cnode@control-node ansible-lab]$ cat file_operation_playbook.yml
---
# file operations
- name: play to create a playbook
hosts: develop
tasks:
- name: Create an empty file
ansible.builtin.file:
path: /home/cnode/devinfo
state: touch
owner: ram
group: devgroup
mode: '0700'
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check file_operation_playbook.yml
playbook: file_operation_playbook.yml
[cnode@control-node ansible-lab]$ ansible-playbook file_operation_playbook.yml
PLAY [play to create a playbook] ****************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Create an empty file] *********************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls -l devinfo
-rwx------. 1 ram devgroup 0 Sep 14 06:48 devinfo
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls -l devinfo
-rwx------. 1 ram devgroup 0 Sep 14 06:48 devinfo
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ ls
ansible.cfg inventory
[cnode@control-node ansible-lab]$ cp ../done/file_operation_playbook.yml file_createdir.yml
[cnode@control-node ansible-lab]$ ls
ansible.cfg file_createdir.yml inventory
[cnode@control-node ansible-lab]$ vim file_createdir.yml
[cnode@control-node ansible-lab]$ cat file_createdir.yml
---
# Create a directory
- name: playbook to create a directory
hosts: develop
tasks:
- name: Create a directory
ansible.builtin.file:
path: /home/cnode/practice/ansible
state: directory
recurse: yes
owner: ram
group: devgroup
mode: '3770'
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check file_createdir.yml
playbook: file_createdir.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check file_createdir.yml
PLAY [playbook to create a directory] ***********************************************
TASK [Gathering Facts] **************************************************************
ok: [dev2]
ok: [dev1]
TASK [Create a directory] ***********************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$ ansible-playbook file_createdir.yml
PLAY [playbook to create a directory] ***********************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Create a directory] ***********************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
practice
[cnode@dev1 ~]$ ls -ld practice
drwxrws--T. 3 ram devgroup 21 Sep 14 08:53 practice
[cnode@dev1 ~]$ cd practice/
-bash: cd: practice/: Permission denied
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
practice
[cnode@dev2 ~]$ ls -ld practice/
drwxrws--T. 3 ram devgroup 21 Sep 14 08:54 practice/
[cnode@dev2 ~]$
# Creating soft link
[cnode@control-node ansible-lab]$ ls
ansible.cfg file_createdir.yml inventory
[cnode@control-node ansible-lab]$ cp file_createdir.yml file_softlink.yml
[cnode@control-node ansible-lab]$ ansible-doc file
/EXAMPLES
[cnode@control-node ansible-lab]$ ls
ansible.cfg file_createdir.yml file_softlink.yml inventory
[cnode@control-node ansible-lab]$ vim file_softlink.yml
[cnode@control-node ansible-lab]$ cat file_softlink.yml
---
# Create a softlink
- name: playbook to create a softlink
hosts: develop
tasks:
- name: Create a softlink (symlink)
ansible.builtin.file:
src: /home/cnode/practice/ansible
dest: /tmp/softps
state: link
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check file_softlink.yml
playbook: file_softlink.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check file_softlink.yml
PLAY [playbook to create a softlink] ************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev2]
ok: [dev1]
TASK [Create a softlink (symlink)] **************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
practice
[cnode@dev1 ~]$ ls -ld
drwx------. 5 cnode cnode 127 Sep 15 10:46 .
[cnode@dev1 ~]$ sudo tree
.
└── practice
└── ansible
3 directories, 0 files
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
practice
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ ls
ansible.cfg file_createdir.yml file_softlink.yml inventory
[cnode@control-node ansible-lab]$ ansible-playbook file_softlink.yml
PLAY [playbook to create a softlink] ************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev2]
ok: [dev1]
TASK [Create a softlink (symlink)] **************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
practice
[cnode@dev1 ~]$ sudo ls /tmp/
softps
[cnode@dev1 ~]$ sudo ls -l /tmp/softps
lrwxrwxrwx. 1 root root 28 Sep 15 10:50 /tmp/softps -> /home/cnode/practice/ansible
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
practice
[cnode@dev2 ~]$ ls /tmp/
softps
[cnode@dev2 ~]$ ls -l /tmp/softps
lrwxrwxrwx. 1 root root 28 Sep 15 10:50 /tmp/softps -> /home/cnode/practice/ansible
[cnode@dev2 ~]$
[cnode@dev1 ~]$ ls -Z devinfo
unconfined_u:object_r:user_home_t:s0 devinfo
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls -Z devinfo
unconfined_u:object_r:user_home_t:s0 devinfo
[cnode@dev2 ~]$
# Changing SELinux Security Context Type to: samba_share_t
[cnode@control-node ansible-lab]$ pwd
/home/cnode/ansible-lab
[cnode@control-node ansible-lab]$ cp ../done/file_operation_playbook.yml file_selinux.yml
[cnode@control-node ansible-lab]$ vim file_selinux.yml
[cnode@control-node ansible-lab]$ cat file_selinux.yml
---
# file operations
- name: play to create a playbook
hosts: develop
tasks:
- name: Create an empty file
ansible.builtin.file:
path: /home/cnode/devinfo
owner: ram
group: devgroup
mode: '0600'
setype: samba_share_t
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check file_selinux.yml
playbook: file_selinux.yml
[cnode@control-node ansible-lab]$ ansible-playbook file_selinux.yml
PLAY [play to create a playbook] ****************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Create an empty file] *********************************************************
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls -Z devinfo
unconfined_u:object_r:samba_share_t:s0 devinfo
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls -Z devinfo
unconfined_u:object_r:samba_share_t:s0 devinfo
[cnode@dev2 ~]$
# fetching log files from different VMs on the control node:
# On hosts machines:
[cnode@dev1 ~]$ ls /var/log
anaconda dnf.log maillog secure
audit dnf.rpm.log maillog-20260906 secure-20260906
btmp firewalld maillog-20260913 secure-20260913
chrony hawkey.log messages spooler
cron hawkey.log-20260906 messages-20260906 spooler-20260906
cron-20260906 hawkey.log-20260913 messages-20260913 spooler-20260913
cron-20260913 httpd private sssd
dnf.librepo.log lastlog samba wtmp
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls /var/log
anaconda dnf.log maillog secure
audit dnf.rpm.log maillog-20260906 secure-20260906
btmp firewalld maillog-20260913 secure-20260913
chrony hawkey.log messages spooler
cron hawkey.log-20260906 messages-20260906 spooler-20260906
cron-20260906 hawkey.log-20260913 messages-20260913 spooler-20260913
cron-20260913 httpd private sssd
dnf.librepo.log lastlog samba wtmp
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ vim fetch_logfiles.yml
[cnode@control-node ansible-lab]$ cat fetch_logfiles.yml
---
# Fetch the files
- name: play to fetch remote files to the local system
hosts: all
tasks:
- name: fetch files from remote hosts to the local
ansible.builtin.fetch:
src: /var/log/secure
dest: /tmp/log/secure
flat: no
[cnode@control-node ansible-lab]$ ls /tmp/log/secure
ls: cannot access '/tmp/log/secure': No such file or directory
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check fetch_logfiles.yml
playbook: fetch_logfiles.yml
[cnode@control-node ansible-lab]$ ansible-playbook fetch_logfiles.yml
PLAY [play to fetch remote files to the local system] *******************************
TASK [Gathering Facts] **************************************************************
ok: [prodserver]
ok: [dev2]
ok: [testserver]
ok: [dev1]
TASK [fetch files from remote hosts to the local] ***********************************
changed: [testserver]
changed: [dev1]
changed: [prodserver]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
prodserver : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
testserver : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$ ls /tmp/log/secure/
dev1 dev2 prodserver testserver
[cnode@control-node ansible-lab]$ ls /tmp/log/secure/testserver/var/log/secure
/tmp/log/secure/testserver/var/log/secure
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ls /tmp/log/secure/dev1/var/log/secure
/tmp/log/secure/dev1/var/log/secure
[cnode@control-node ansible-lab]$
# adding lines on files
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
- name: play to add data in a file
hosts: develop
tasks:
- name: Add a line to a file if the file does not exist, without passing regexp
ansible.builtin.lineinfile:
path: /home/cnode/file1
line: this is the first line on 192.168.254.16 foo.lab.net foo
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check lineinfile_addline.yml
playbook: lineinfile_addline.yml
[cnode@control-node ansible-lab]$ ansible-playbook --check lineinfile_addline.yml
PLAY [play to add data in a file] ***************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Add a line to a file if the file does not exist, without passing regexp] ******
fatal: [dev2]: FAILED! => {"changed": false, "msg": "Destination /home/cnode/file1 does not exist !", "rc": 257}
fatal: [dev1]: FAILED! => {"changed": false, "msg": "Destination /home/cnode/file1 does not exist !", "rc": 257}
PLAY RECAP **************************************************************************
dev1 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
dev2 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
- name: play to add data in a file
hosts: develop
tasks:
- name: Add a line to a file if the file does not exist, without passing regexp
ansible.builtin.lineinfile:
path: /home/cnode/file1
line: this is the first line on 192.168.254.16 foo.lab.net foo
create: yes
[cnode@control-node ansible-lab]$ ansible-playbook --check lineinfile_addline.yml
PLAY [play to add data in a file] ***************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Add a line to a file if the file does not exist, without passing regexp] ******
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
- name: play to add data in a file
hosts: develop
tasks:
- name: Add a line to a file if the file does not exist, without passing regexp
ansible.builtin.lineinfile:
path: /home/cnode/devinfo
line: this is the first line on 192.168.254.16 foo.lab.net foo
create: yes
[cnode@control-node ansible-lab]$ ansible-playbook lineinfile_addline.yml
PLAY [play to add data in a file] ***************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Add a line to a file if the file does not exist, without passing regexp] ******
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ sudo cat devinfo
this is the first line on 192.168.254.16 foo.lab.net foo
[cnode@dev1 ~]$
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
- name: play to add data in a file
hosts: develop
tasks:
- name: Add a line to a file if the file does not exist, without passing regexp
ansible.builtin.lineinfile:
path: /home/cnode/devinfo
line: this is the second line added in devinfo
state: present
[cnode@control-node ansible-lab]$ ansible-playbook lineinfile_addline.yml
[cnode@dev1 ~]$ sudo cat devinfo
this is the first line on 192.168.254.16 foo.lab.net foo
this is the second line added in devinfo
[cnode@dev1 ~]$
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
- name: play to add data in a file
hosts: develop
tasks:
- name: Add a line to a file if the file does not exist, without passing regexp
ansible.builtin.lineinfile:
path: /home/cnode/devinfo
line: this is the second line added in devinfo
state: absent
[cnode@control-node ansible-lab]$ ansible-playbook lineinfile_addline.yml
PLAY [play to add data in a file] ***************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Add a line to a file if the file does not exist, without passing regexp] ******
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ sudo cat devinfo
this is the first line on 192.168.254.16 foo.lab.net foo
[cnode@dev1 ~]$
# Changing the SELinux
[cnode@dev1 ~]$ getenforce
Enforcing
[cnode@dev1 ~]$ cat /etc/sysconfig/selinux
...
SELINUX=enforcing
...
[cnode@dev1 ~]$ cat /etc/selinux/config
...
SELINUX=enforcing
...
[cnode@control-node ansible-lab]$ vim lineinfile_addline.yml
[cnode@control-node ansible-lab]$ cat lineinfile_addline.yml
---
# Search and replace
- name: play to add data in a file
hosts: develop
tasks:
- name: Change SELinux mode
ansible.builtin.lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=permissive
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check lineinfile_addline.yml
playbook: lineinfile_addline.yml
[cnode@control-node ansible-lab]$ ansible-playbook lineinfile_addline.yml
PLAY [play to add data in a file] ***************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev2]
ok: [dev1]
TASK [Change SELinux mode] **********************************************************
changed: [dev1]
changed: [dev2]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ cat /etc/selinux/config
...
SELINUX=permissive
...
# blockinfile multiple lines
[cnode@dev1 ~]$ ls
devinfo practice
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
devinfo practice
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ vim blockinfile_addblock.yml
[cnode@control-node ansible-lab]$ ansible-playbook --syntax-check blockinfile_addblock.yml
playbook: blockinfile_addblock.yml
[cnode@control-node ansible-lab]$ cat blockinfile_addblock.yml
---
# Add a block of lines in a file
- name: To add a block in file
hosts: develop
tasks:
- name: Insert/Update multiple lines
ansible.builtin.blockinfile:
path: /home/cnode/devinfo
append_newline: true
prepend_newline: true
block: |
Match User ansible-agent -- addedline1
PasswordAuthentication no -- addedline2
<add multiple lines>
[cnode@control-node ansible-lab]$ ansible-playbook blockinfile_addblock.yml
PLAY [To add a block in file] *******************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev2]
ok: [dev1]
TASK [Insert/Update multiple lines] *************************************************
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ sudo cat devinfo
this is the first line on 192.168.254.16 foo.lab.net foo
# BEGIN ANSIBLE MANAGED BLOCK
Match User ansible-agent -- addedline1
PasswordAuthentication no -- addedline2
<add multiple lines>
# END ANSIBLE MANAGED BLOCK
[cnode@dev1 ~]$
Delete a file
[cnode@dev1 ~]$ ls
devinfo practice
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
devinfo practice
[cnode@dev2 ~]$
[cnode@control-node ansible-lab]$ vim file_deletefile.yml
[cnode@control-node ansible-lab]$ cat file_deletefile.yml
---
# file operation: delete a file
- name: play to delete a file
hosts: develop
tasks:
- name: Delete the existing files
ansible.builtin.file:
path: /home/cnode/devinfo
state: absent
[cnode@control-node ansible-lab]$
[cnode@control-node ansible-lab]$ ansible-playbook file_deletefile.yml
PLAY [play to delete a file] ********************************************************
TASK [Gathering Facts] **************************************************************
ok: [dev1]
ok: [dev2]
TASK [Delete the existing files] ****************************************************
changed: [dev2]
changed: [dev1]
PLAY RECAP **************************************************************************
dev1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[cnode@control-node ansible-lab]$
[cnode@dev1 ~]$ ls
practice
[cnode@dev1 ~]$
[cnode@dev2 ~]$ ls
devinfo practice
[cnode@dev2 ~]$ ls
practice
[cnode@dev2 ~]$