Organizing with Roles

AnsibleBeginner
Practice Now

Introduction

When you start with Ansible, putting everything in one big playbook.yml file is fine. But as your automation grows to hundreds of lines, that file becomes a mess.

The solution is Ansible roles.

Roles are like folders in a file cabinet. Instead of one giant document, you separate things into logical folders: one folder for "Web Server" tasks, one for "Database" tasks, etc.

Roles matter because automation eventually becomes software engineering. Once playbooks grow beyond a few tasks, structure, naming, and reuse become as important as simply making the first run succeed.

In this lab, you will:

  1. Create a standardized Role structure using ansible-galaxy.
  2. Move tasks into that Role.
  3. Run the Role from a simple "Master Playbook".

Roles matter because scalable automation needs structure. As codebases grow, organization becomes just as important as getting the first successful run.

Initialize a Role

First, let's create the folder structure. You could make all the folders manually, but Ansible includes a tool called ansible-galaxy that does it for you.

This standard layout is valuable because it gives every role predictable places for tasks, variables, files, templates, and handlers. Teams can read each other's automation more easily when that structure stays consistent.

Go to your project directory:

cd ~/project

Create a directory to hold your roles:

mkdir roles

Now, create a new role named myrole. Think of this as creating a "package" or "module" for your automation.

ansible-galaxy init roles/myrole

Let's look at what it created:

ls -R roles/myrole

You will see many folders (tasks, handlers, vars, etc.).

  • tasks: Where the actual steps (install, start, copy) go.
  • vars: Where variables go.
  • files: Where static files (like images) go.

We will focus on the tasks folder today.

Define Role Tasks

Now we need to put some work into our role. The main list of tasks for a role lives in tasks/main.yml.

We will create a simple task that installs the tree command (a useful utility for viewing directory structures).

Open the role's task file:

nano roles/myrole/tasks/main.yml

Add the following content. Notice we do not start with tasks: here, because we are already inside the tasks file!

---
## tasks file for roles/myrole
- name: Ensure tree is installed
  apt:
    name: tree
    state: present
  become: yes

Key Difference: In a normal playbook, you have a tasks: section. Inside a role, the file is the list of tasks, so you just start listing them directly.

That separation is one reason roles improve reuse. The role owns a focused slice of automation logic, while the playbook decides when and where to include it.

Save and exit.

Create Master Playbook

Now you have a Role, but a Role doesn't run by itself. You need a "Master Playbook" to call it.

Create a file named site.yml in your main project folder:

nano ~/project/site.yml

This playbook will be very short. It just says "On these hosts, run this role."

At this point the playbook becomes more of an orchestrator than a container for all details. That is the architectural shift roles are meant to create.

---
- hosts: localhost
  connection: local
  roles:
    - myrole

Understanding the code:

  • roles:: Instead of a tasks: list, we provide a list of roles.
  • - myrole: Ansible looks for a folder named myrole inside the roles/ directory and executes whatever is in tasks/main.yml.

Save and exit.

Validate and Run

Before we run it, let's make sure we didn't make any typing mistakes. Ansible has a built-in syntax checker.

Run this command:

ansible-playbook -i inventory --syntax-check site.yml

If everything is good, it will just print playbook: site.yml.

If there are errors, read the message carefully—it usually points to the exact line number where the indentation is wrong.

Now, run the playbook for real:

ansible-playbook -i inventory site.yml

You should see it execute the task from your role: TASK [myrole : Ensure tree is installed] ... changed

Summary

In this lab, you learned the "Professional" way to structure Ansible.

  1. Initialized a Role: Using ansible-galaxy to create the standard folder structure.
  2. Defined Tasks: Placed your logic inside tasks/main.yml.
  3. Used the Role: Called the role from a clean, simple site.yml master playbook.

As you write more automation, you will create roles for everything (e.g., apache, mysql, common), making your code reusable and easy to read.