Introduction
Roles package defaults, tasks, templates, files, and handlers into a reusable structure. They keep playbooks short and make automation easier to share.
In this lab, you will create a role by hand, add defaults, a template, and tasks, then apply it to two host aliases.
Create a Role Practice Project
In this step, you will create a project with a roles directory and two local web host aliases.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory,roles,playbooks,managed,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
roles_path = ./roles
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[web]
web1 ansible_connection=local
web2 ansible_connection=local
EOF
The roles_path = ./roles setting tells Ansible where to look for role names used by playbooks. Without it, Ansible might search only system or user-level role paths.
Create the Role Directory Structure
In this step, you will create the key role directories. defaults stores low-precedence variables, tasks stores task logic, and templates stores Jinja2 templates.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
mkdir -p roles/web_banner/{defaults,tasks,templates}
find roles/web_banner -maxdepth 2 -type d | sort
The output should show the role root plus defaults, tasks, and templates. Those names are meaningful to Ansible; for example, tasks/main.yml is the task entry point for the role.
Add Role Defaults and a Template
In this step, you will add default variables and a template. The role will use these values unless a playbook or inventory overrides them. Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
cat > roles/web_banner/defaults/main.yml <<'EOF'
---
banner_message: Welcome to RHCE Ansible Prep
EOF
cat > roles/web_banner/templates/banner.txt.j2 <<'EOF'
Host: {{ inventory_hostname }}
Message: {{ banner_message }}
EOF
Defaults are low-precedence role variables. They give the role a usable value when the playbook or inventory does not provide one, while still allowing callers to override it later.
cat roles/web_banner/defaults/main.yml roles/web_banner/templates/banner.txt.j2
The template combines the current host alias with the default message. When the role runs for two hosts, the same template should render two different Host: lines.
Add Role Tasks and Apply the Role
In this step, you will add tasks/main.yml and a playbook that applies the role. The role creates a host directory and renders one banner file per host.
Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
cat > roles/web_banner/tasks/main.yml <<'EOF'
---
- name: Ensure host banner directory exists
ansible.builtin.file:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}"
state: directory
mode: '0755'
- name: Render host banner
ansible.builtin.template:
src: banner.txt.j2
dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/banner.txt"
mode: '0644'
EOF
cat > playbooks/apply-role.yml <<'EOF'
---
- name: Apply reusable web banner role
hosts: web
gather_facts: false
roles:
- role: web_banner
EOF
The role task file contains the implementation, while playbooks/apply-role.yml stays short and only names the role. This is the main value of roles: reusable structure without repeating every task in every playbook.
ansible-playbook playbooks/apply-role.yml --syntax-check
Run the Role-Based Playbook
In this step, you will run the playbook and inspect the rendered files. The playbook stays short because the role carries the reusable implementation. Before running commands in this step, return to the Ansible project directory. This keeps the commands stable even when LabEx runs each step separately.
cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/apply-role.yml | tee reports/role-run.txt
The run should execute the role once per host alias in the web group. A successful recap with failed=0 means the role was found through roles_path and its tasks completed.
cat managed/web1/banner.txt managed/web2/banner.txt
The rendered files should share the same message but have different Host: lines. That proves the role reused the same logic while still rendering per-host data.
Summary
You built a reusable role structure, added defaults, tasks, and a template, applied the role from a playbook, and verified the rendered output.


