Ansible Galaxy: Installing and Creating Roles for RHCE (2026 Guide)

By LinuxCert.Guru Team·

Objective

This guide covers Ansible Galaxy and role-based automation for RHCE preparation. By the end, you will know how to:

  • Understand the Ansible role directory structure and why roles exist
  • Create a custom role using the ansible-galaxy init command
  • Write role tasks, handlers, variables, and defaults
  • Install community roles from Ansible Galaxy using a requirements file
  • Apply both custom and community roles in a single playbook
  • Verify that services deployed through roles are correctly configured

As playbooks grow, they become harder to read, harder to maintain, and harder to reuse across projects. Roles solve this by organising automation into a predictable directory structure where tasks, variables, handlers, templates, and files all have a defined home. Ansible Galaxy extends this further by giving you access to thousands of community-maintained roles so you don't have to write everything from scratch.

What Is a Role

A role is a structured way to group related Ansible automation. Instead of one long playbook file, a role splits the work into separate files for tasks, variables, handlers, templates, and defaults. Each file has a defined purpose and location. Ansible loads them automatically when the role is called.

Directory Purpose Key File
tasks/ The main list of tasks the role executes main.yml
handlers/ Handlers triggered by notify directives in tasks main.yml
defaults/ Default variable values, lowest precedence, easily overridden main.yml
vars/ Role variables with higher precedence than defaults main.yml
templates/ Jinja2 template files deployed by the role *.j2
files/ Static files copied to managed hosts Any file
meta/ Role metadata including dependencies on other roles main.yml

What Is Ansible Galaxy

Ansible Galaxy is the official community hub for sharing and downloading Ansible roles. Instead of writing a role for a common task like firewall management, time synchronisation, or package installation, you can download a tested, community-maintained role and use it immediately in your playbook.

Approach When to Use Source
Custom role Organisation-specific logic, proprietary applications, unique configuration Written by you
Community role Common services: web servers, databases, firewalls, monitoring, time sync Ansible Galaxy
Both combined Most real-world automation: community roles for infrastructure, custom roles for application logic Mixed

Step 1: Create a Custom Role Structure

The ansible-galaxy init command creates the full role directory structure automatically. You never need to create these folders manually.

# Create the roles directory in your project
mkdir -p ~/ansible-project/roles
cd ~/ansible-project

# Create a new role called chrony
ansible-galaxy init roles/chrony

# View the generated structure
tree roles/chrony

The generated structure looks like this:

roles/chrony/
├── defaults/
│   └── main.yml
├── files/
├── handlers/
│   └── main.yml
├── meta/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml

Step 2: Write the Custom Role

This example creates a role that installs and configures the Chrony NTP service for time synchronisation.

defaults/main.yml: Set Default Variables

# roles/chrony/defaults/main.yml
---
chrony_ntp_servers:
  - 0.pool.ntp.org
  - 1.pool.ntp.org
  - 2.pool.ntp.org
  - 3.pool.ntp.org

chrony_service_state: started
chrony_service_enabled: true

tasks/main.yml: Define the Role Tasks

# roles/chrony/tasks/main.yml
---
- name: Install chrony package
  ansible.builtin.dnf:
    name: chrony
    state: present

- name: Deploy chrony configuration from template
  ansible.builtin.template:
    src: chrony.conf.j2
    dest: /etc/chrony.conf
    owner: root
    group: root
    mode: '0644'
  notify: Restart chronyd

- name: Ensure chronyd service is in desired state
  ansible.builtin.systemd:
    name: chronyd
    state: "{{ chrony_service_state }}"
    enabled: "{{ chrony_service_enabled }}"

handlers/main.yml: Define the Handler

# roles/chrony/handlers/main.yml
---
- name: Restart chronyd
  ansible.builtin.systemd:
    name: chronyd
    state: restarted

templates/chrony.conf.j2: The Configuration Template

{# roles/chrony/templates/chrony.conf.j2 #}
{# Generated by Ansible on {{ ansible_fqdn }} #}

{% for server in chrony_ntp_servers %}
server {{ server }} iburst
{% endfor %}

driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony

Step 3: Install a Community Role from Ansible Galaxy

Using a requirements file is the correct way to manage Galaxy dependencies. It makes your role list repeatable, version-controlled, and shareable with your team.

Create the Requirements File

# requirements.yml - defines community roles to install
---
roles:
  - name: geerlingguy.firewall
    version: "2.4.0"

  - name: geerlingguy.ntp
    version: "1.6.3"

Install Roles from the Requirements File

# Install all roles defined in requirements.yml into the roles/ directory
ansible-galaxy install -r requirements.yml -p roles/

# Verify the roles were installed
ansible-galaxy list

# View the installed role directory
ls roles/

Install a Single Role Directly

# Install a single role by name
ansible-galaxy install geerlingguy.firewall -p roles/

# Search for roles on Galaxy before installing
ansible-galaxy search firewall --author geerlingguy

# Get information about a role before installing
ansible-galaxy info geerlingguy.firewall

Step 4: Apply Both Roles in a Playbook

# site.yml - main playbook applying custom and community roles
---
- name: Configure all managed hosts
  hosts: all
  become: true

  vars:
    # Override chrony role defaults for this environment
    chrony_ntp_servers:
      - ntp1.example.com
      - ntp2.example.com

    # Variables for the community firewall role
    firewall_allowed_tcp_ports:
      - "22"
      - "80"
      - "443"
    firewall_allowed_udp_ports:
      - "123"   # NTP

  roles:
    # Community role from Ansible Galaxy (installed via requirements.yml)
    - role: geerlingguy.firewall

    # Custom role written locally
    - role: chrony

Run the Playbook

# Check syntax before running
ansible-playbook site.yml --syntax-check

# Run in check mode (dry run, no changes)
ansible-playbook site.yml --check

# Apply the playbook
ansible-playbook site.yml

# Run with verbose output to see each task
ansible-playbook site.yml -v

Step 5: Verify the Deployment

# Verify chronyd is running and enabled
ansible all -m ansible.builtin.systemd -a "name=chronyd" -b

# Check the deployed chrony configuration
ansible all -m ansible.builtin.command -a "cat /etc/chrony.conf" -b

# Verify NTP synchronisation status
ansible all -m ansible.builtin.command -a "chronyc tracking" -b

# Check the firewall rules applied by the community role
ansible all -m ansible.builtin.command -a "firewall-cmd --list-all" -b

ansible.cfg: Configuring the Role Path

Ansible looks for roles in specific locations. Configuring ansible.cfg in your project directory tells Ansible where to find your roles so you don't need to specify the path every time.

# ansible.cfg in your project root
[defaults]
inventory = inventory
roles_path = roles:~/.ansible/roles
remote_user = ansible
host_key_checking = False

[privilege_escalation]
become = True
become_method = sudo
become_user = root

The roles_path setting accepts multiple directories separated by colons. Ansible searches them in order. The example above checks the local roles/ directory first (for project-specific roles), then ~/.ansible/roles (for roles installed globally by Galaxy).

Overriding Role Variables

Defaults defined in roles/rolename/defaults/main.yml are intentionally easy to override. This is what makes roles reusable: the defaults work for most cases, and you override only what differs in your environment.

Override Method Where to Set It Precedence
Role defaults roles/rolename/defaults/main.yml Lowest
Inventory group vars group_vars/groupname.yml Medium
Inventory host vars host_vars/hostname.yml Medium-high
Playbook vars vars: section in the playbook High
Command-line extra vars -e "var=value" when running the playbook Highest

Useful ansible-galaxy Commands

# Create a new role skeleton
ansible-galaxy init roles/myrole

# Install roles from a requirements file
ansible-galaxy install -r requirements.yml -p roles/

# Install a specific role
ansible-galaxy install author.rolename -p roles/

# Install a specific version of a role
ansible-galaxy install author.rolename,v1.2.0 -p roles/

# List all installed roles
ansible-galaxy list

# Search for roles on Galaxy
ansible-galaxy search keyword

# Get details about a role
ansible-galaxy info author.rolename

# Remove an installed role
ansible-galaxy remove author.rolename

Common Mistakes

  • Not using a requirements file. Installing roles with direct ansible-galaxy install commands without a requirements file makes the installation non-repeatable. Anyone cloning your project won't know which roles to install or at which version.
    • Always maintain a requirements.yml and commit it to version control alongside your playbooks
  • Putting role variables in vars/ instead of defaults/. Variables in vars/main.yml have higher precedence and are harder to override. Use defaults/main.yml for anything a user of the role might want to change. Use vars/main.yml only for internal role values that should never be overridden.
    • If you're writing a role for others to use, defaults are almost always the right choice
  • Calling the wrong role name after installation. When you install a Galaxy role like geerlingguy.firewall, it installs with the name geerlingguy.firewall (including the author prefix). Use that full name in your playbook's roles: list.
    • Check the exact name with ansible-galaxy list after installation
  • Forgetting the -p roles/ flag when installing Galaxy roles. Without specifying the path, roles install to ~/.ansible/roles globally instead of your project's roles/ directory. This makes the project non-portable.
    • Always specify -p roles/ or configure roles_path in ansible.cfg
  • Not reading the community role's README before using it. Community roles have required variables that have no defaults, optional variables that change behaviour significantly, and supported platform lists. Using a role without reading its README leads to unexpected failures.
    • Run ansible-galaxy info author.rolename or check galaxy.ansible.com before integrating a community role

Ansible Galaxy and the RHCE Exam

Role-based automation and Ansible Galaxy are explicit RHCE exam objectives. Common exam task patterns include:

  • Create a role using ansible-galaxy init with the correct directory structure
  • Write role tasks, handlers, defaults, and a template that the role deploys
  • Install a community role from Ansible Galaxy using either a direct command or a requirements file
  • Write a playbook that applies both a custom role and a downloaded Galaxy role to managed hosts
  • Override role default variables in the playbook to customise the role's behaviour

The exam tests that you understand the role directory structure well enough to write tasks in the right file and that you can integrate community roles without treating them as black boxes. Knowing which file does what inside a role is as important as knowing how to use Galaxy to get the role in the first place.

Practice This in a Real Environment

Roles are one of those topics where reading the directory structure on a page and actually building one are very different experiences. The first time you write a role with a template, a handler, and a default variable that gets overridden in the playbook, the whole system clicks. That understanding doesn't come from memorising folder names.

LinuxCert.Guru has a dedicated hands-on lab for this: Ansible Galaxy. It covers creating a local Chrony role, installing a community firewall role from Galaxy using a requirements file, and applying both in a single playbook on real RHEL hosts with auto-graded tasks.

Practice the Ansible Galaxy lab at LinuxCert.Guru → https://linuxcert.guru/rhce/?name=rhce-ansible-galaxy

Conclusion

Ansible Galaxy and roles together give you modular, reusable, maintainable automation. Custom roles organise your own logic. Community roles give you tested automation for common services without writing it yourself. Used together, they make playbooks shorter, cleaner, and easier to manage as infrastructure grows.

  • Use ansible-galaxy init roles/rolename to create the correct directory structure automatically
  • Put default variable values in defaults/main.yml so they can be overridden easily
  • Put tasks in tasks/main.yml, handlers in handlers/main.yml, and templates in templates/
  • Always use a requirements.yml file to declare Galaxy role dependencies with version pins
  • Install Galaxy roles with ansible-galaxy install -r requirements.yml -p roles/
  • Read the community role README before using it: required variables and supported platforms matter
  • Apply roles in a playbook with the roles: list and override defaults in the playbook vars: section

 

$_
Ready to go beyond reading?Practice with free, auto-graded RHCSA labs.
Start free →