As my career in IT Infrastructure has progressed, terminology like “managing at scale”, “infrastructure as code”, “configuration as code”, etc., has made its way into my vocabulary and day-to-day work. One tool I like to make use of is Ansible.
https://ansible.com describes Ansible as follows:
“Ansible is an open-source, command-line IT automation software application written in Python. It can configure systems, deploy software, and orchestrate advanced workflows to support application deployment, system updates, and more.
Ansible’s main strengths are simplicity and ease of use.”
You can do quite a lot with Ansible, but sometimes it’s hard to find a solid example of something you can do with it that is both immediately useful and not a huge undertaking. This article will describe how to set up a simple directory structure, as well as give you a working playbook that calls a role that will patch and, if needed, reboot your Red Hat Enterprise Linux servers.
First, let’s go over the filesystem layout I typically choose to work with. Further information is available here.

In my case, I have this directory structure in ~/git/ansible. I strongly recommend you leverage source control, be that GitHub or GitLab, or something else. Assume I have remote_user configured in ansible.cfg with the right to SSH and sudo to root on the target hosts defined in the inventory file.
I have created a _role_template directory under roles. This is a cheat sheet, if you will, for me to remember the most common components of a role. For what we’re doing here, the patching role only needs a main.yml file under roles/patching/tasks.
Ansible Role
Now for the code. Below are the contents of roles/patching/tasks/main.yml…
---
- name: DNF update the system
ansible.builtin.dnf:
name: "*"
state: latest
update_only: true
when:
- ansible_facts['os_family'] == 'RedHat' and ansible_facts ['distribution_major_version'] >= '8'
- name: YUM update the system
ansible.builtin.yum:
name: "*"
state: latest
update_only: true
when:
- ansible_facts['os_family'] == 'RedHat' and ansible_facts ['distribution_major_version'] == '7'
- name: Reboot required
ansible.builtin.command: "/usr/bin/needs-restarting -r"
register: reboot_required
ignore_errors: true
changed_when: reboot_required != 0
failed_when: false
- name: Rebooting
ansible.builtin.reboot:
post_reboot_delay: 60
throttle: 1
when: reboot_required.rc == 1
As you can see, the tasks in this file execute patching using ‘dnf’ for RHEL 8+ or ‘yum’ for RHEL 7. Using these conditional blocks allows me to use a single role, regardless of OS major release, instead of having to author and maintain separate roles for each scenario.
The tasks then continue to evaluate whether or not the target systems needs to reboot after patching, and based on that, either reboot them or not.
Ansible Playbook
On to the playbook, patching-conditional-role.yml. Here is where we call the patching role:
---
- name: Patching Linux Servers
hosts: all
gather_facts: true
become: true
roles:
- patching
As you can see, the playbook is very simple in this case, with all the heavy lifting taking place in the role. Using roles allows you to easily reuse code, without having to duplicate it. The patching role can be incorporate as-is into additional playbooks that may have additional roles and/or plays included.
Conclusion
In this high-level overview of Ansible, we have looked at the directory structure and the use of a role in a playbook to patch your RHEL server infrastructure. You can easily leverage this code in your own environment to conditionally patch and reboot RHEL servers. If you’ve found this useful, or have ideas on how to expand this – or other- Ansible playbook/role content, please comment below.
If you’re looking for assistance with Ansible playbooks, roles, or proper design, implementation, and maintenance of Ansible Automation Platform, reach out at https://brianalcorncom.wordpress.com/consulting/. Also, if you’re looking for more Ansible content, check out this post.





One response to “A Beginner Ansible Playbook that DOES Something”
[…] For more detail about setting up an Ansible directory structure, follow this link. […]