Create and Apply a Reusable Role

AnsibleBeginner
Practice Now

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.