Docs / Automation & IaC / How to Create Ansible Roles for Reusable Automation

How to Create Ansible Roles for Reusable Automation

By Admin · Mar 2, 2026 · Updated Apr 25, 2026 · 26 views · 3 min read

How to Create Ansible Roles for Reusable Automation

Ansible roles let you organize playbooks into modular, reusable components. Instead of monolithic playbooks, roles break your Breeze server configuration into self-contained units that can be shared across projects and teams.

Role Directory Structure

Initialize a new role with the ansible-galaxy command:

ansible-galaxy role init roles/webserver

# This creates the standard structure:
roles/webserver/
├── defaults/
│   └── main.yml       # Default variables (lowest priority)
├── files/
│   └──                # Static files to copy
├── handlers/
│   └── main.yml       # Handler definitions (e.g., restart services)
├── meta/
│   └── main.yml       # Role metadata and dependencies
├── tasks/
│   └── main.yml       # Main task list
├── templates/
│   └──                # Jinja2 templates
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml       # Role variables (higher priority)

Writing Role Tasks

Define your tasks in roles/webserver/tasks/main.yml:

---
# roles/webserver/tasks/main.yml
- name: Install Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Deploy Nginx configuration
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  notify: Restart Nginx

- name: Deploy site configuration
  template:
    src: site.conf.j2
    dest: "/etc/nginx/sites-available/{{ site_domain }}"
  notify: Reload Nginx

- name: Enable site
  file:
    src: "/etc/nginx/sites-available/{{ site_domain }}"
    dest: "/etc/nginx/sites-enabled/{{ site_domain }}"
    state: link
  notify: Reload Nginx

- name: Ensure Nginx is running
  service:
    name: nginx
    state: started
    enabled: yes

Defining Handlers

Handlers run only when notified by tasks, typically for service restarts:

---
# roles/webserver/handlers/main.yml
- name: Restart Nginx
  service:
    name: nginx
    state: restarted

- name: Reload Nginx
  service:
    name: nginx
    state: reloaded

Setting Default Variables

Provide sensible defaults in roles/webserver/defaults/main.yml:

---
# roles/webserver/defaults/main.yml
site_domain: "example.com"
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_client_max_body_size: "64m"
ssl_enabled: true
ssl_certificate_path: "/etc/letsencrypt/live/{{ site_domain }}/fullchain.pem"
ssl_key_path: "/etc/letsencrypt/live/{{ site_domain }}/privkey.pem"

Using the Role in a Playbook

Apply roles to your Breeze servers in a playbook:

---
# site.yml
- hosts: breeze_web_servers
  become: yes
  roles:
    - role: webserver
      vars:
        site_domain: "myapp.com"
        nginx_worker_connections: 2048

    - role: firewall
    - role: monitoring

Role Dependencies

Declare role dependencies in meta/main.yml so prerequisite roles run automatically:

---
# roles/webserver/meta/main.yml
dependencies:
  - role: common
  - role: firewall
    vars:
      firewall_open_ports:
        - 80
        - 443

Best Practices

  • Keep roles focused — each role should handle one concern (web server, database, monitoring)
  • Use defaults generously — provide defaults so roles work out of the box
  • Tag your tasks — add tags to allow selective execution with --tags
  • Document variables — list all variables and their defaults in the role README
  • Test roles independently — use the tests/ directory or tools like Molecule
  • Version roles — use Git tags to version roles used across multiple projects

Well-structured roles make your Breeze infrastructure automation modular, testable, and easy to maintain across growing environments.

Was this article helpful?