In order to highlight the interest of using roles, I suggest you to use the alemorvan/patchmanagement role, which will allow you to perform a lot of tasks (pre-update or post-update for example) during your update process, in only a few lines of code.
You can check the code in the github repo of the role here.
Install the role. This needs only one command:
ansible-galaxy role install alemorvan.patchmanagement
With this role, you can add your own tasks for all your inventory or for only your targeted node.
Let's create tasks that will be run before and after the update process:
Create the custom_tasks folder:
mkdir custom_tasks
Create the custom_tasks/pm_before_update_tasks_file.yml (feel free to change the name and the content of this file)
---
- name: sample task before the update process
debug:
msg: "This is a sample tasks, feel free to add your own test task"
Create the custom_tasks/pm_after_update_tasks_file.yml (feel free to change the name and the content of this file)
---
- name: sample task after the update process
debug:
msg: "This is a sample tasks, feel free to add your own test task"
And launch your first Patch Management:
ansible-playbook patchmanagement.yml
PLAY [Start a Patch Management] *************************************************************************
TASK [Gathering Facts] **********************************************************************************
ok: [192.168.1.11]
TASK [Include patchmanagement] **************************************************************************
TASK [alemorvan.patchmanagement : MAIN | Linux Patch Management Job] ************************************
ok: [192.168.1.11] => {
"msg": "Start 192 patch management"
}
...
TASK [alemorvan.patchmanagement : sample task before the update process] ********************************
ok: [192.168.1.11] => {
"msg": "This is a sample tasks, feel free to add your own test task"
}
...
TASK [alemorvan.patchmanagement : MAIN | We can now patch] **********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/patch.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : PATCH | Tasks depends on distribution] ********************************
ok: [192.168.1.11] => {
"ansible_distribution": "Rocky"
}
TASK [alemorvan.patchmanagement : PATCH | Include tasks for CentOS & RedHat tasks] **********************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/linux_tasks/redhat_centos.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : RHEL CENTOS | yum clean all] ******************************************
changed: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Ensure yum-utils is installed] **************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Remove old kernels] *************************************
skipping: [192.168.1.11]
TASK [alemorvan.patchmanagement : RHEL CENTOS | Update rpm package with yum] ****************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : PATCH | Inlude tasks for Debian & Ubuntu tasks] ***********************
skipping: [192.168.1.11]
TASK [alemorvan.patchmanagement : MAIN | We can now reboot] *********************************************
included: /home/ansible/.ansible/roles/alemorvan.patchmanagement/tasks/reboot.yml for 192.168.1.11
TASK [alemorvan.patchmanagement : REBOOT | Reboot triggered] ********************************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : REBOOT | Ensure we are not in rescue mode] ****************************
ok: [192.168.1.11]
...
TASK [alemorvan.patchmanagement : FACTS | Insert fact file] *********************************************
ok: [192.168.1.11]
TASK [alemorvan.patchmanagement : FACTS | Save date of last PM] *****************************************
ok: [192.168.1.11]
...
TASK [alemorvan.patchmanagement : sample task after the update process] *********************************
ok: [192.168.1.11] => {
"msg": "This is a sample tasks, feel free to add your own test task"
}
PLAY RECAP **********************************************************************************************
192.168.1.11 : ok=31 changed=1 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
Pretty easy for such a complex process, isn't it?
This is just one example of what can be done using roles made available by the community. Have a look at galaxy.ansible.com to discover the roles that could be useful for you!
You can also create your own roles for your own needs and publish them on the Internet if you feel like it. This is what we will briefly cover in the next chapter.
Roles allow you to do away with the need to include files. There is no need to specify file paths or include directives in playbooks. You just have to specify a task, and Ansible takes care of the inclusions.
The structure of a role is fairly obvious to understand.
Variables are simply stored either in vars/main.yml if the variables are not to be overridden, or in default/main.yml if you want to leave the possibility of overriding the variable content from outside your role.
The handlers, files, and templates needed for your code are stored in handlers/main.yml, files and templates respectively.
All that remains is to define the code for your role's tasks in tasks/main.yml.
Once all this is working well, you can use this role in your playbooks. You will be able to use your role without worrying about the technical aspect of its tasks, while customizing its operation with variables.
Let's implement this with a "go anywhere" role that will create a default user and install software packages. This role can be systematically applied to all your servers.
Congratulations! You are now able to create great things with a playbook of only a few lines.
Let's see the use of default variables.
Create a list of packages to install by default on your servers and an empty list of packages to uninstall. Edit the defaults/main.yml files and add those two lists:
rocky8_default_packages:
- tree
- vim
rocky8_remove_packages: []
Obviously, there is no limit to how much you can improve your role. Imagine that for one of your servers, you need a package that is in the list of those to be uninstalled. You could then, for example, create a new list that can be overridden and then remove from the list of packages to be uninstalled those in the list of specific packages to be installed by using the jinja difference() filter.
ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/download/community-general-3.3.2.tar.gz to /home/ansible/.ansible/tmp/ansible-local-51384hsuhf3t5/tmpr_c9qrt1/community-general-3.3.2-f4q9u4dg
Installing 'community.general:3.3.2' to '/home/ansible/.ansible/collections/ansible_collections/community/general'
community.general:3.3.2 was installed successfully
We can now use the newly available module yum_versionlock: