Skip to content

Ansible Roles

Overview

Understanding how to create, use, and manage Ansible roles effectively.

Role Structure

roles/
└── webserver/
    ├── defaults/        # Default variables
    │   └── main.yml
    ├── files/          # Static files
    │   └── nginx.conf
    ├── handlers/       # Event handlers
    │   └── main.yml
    ├── meta/          # Role metadata
    │   └── main.yml
    ├── tasks/         # Core logic
    │   ├── main.yml
    │   ├── install.yml
    │   └── configure.yml
    ├── templates/     # Jinja2 templates
    │   └── vhost.conf.j2
    └── vars/          # Fixed variables
        └── main.yml

Role Creation

Initialize New Role

ansible-galaxy init webserver

Role Components

defaults/main.yml

---
# Default variable values
nginx_port: 80
worker_processes: auto
ssl_enabled: false

tasks/main.yml

---
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: security.yml

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

handlers/main.yml

---
- name: Restart nginx
  service:
    name: nginx
    state: restarted

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

meta/main.yml

---
galaxy_info:
  author: Your Name
  description: NGINX web server installation and configuration
  company: Your Company
  license: MIT
  min_ansible_version: 2.9
  platforms:
    - name: Ubuntu
      versions:
        - focal
        - jammy
  galaxy_tags:
    - web
    - nginx
    - http

dependencies:
  - role: common
    version: 1.0.0

Role Usage

Simple Role Include

---
- hosts: webservers
  roles:
    - webserver

Role with Parameters

---
- hosts: webservers
  roles:
    - role: webserver
      vars:
        nginx_port: 8080
        ssl_enabled: true

Conditional Role Usage

---
- hosts: all
  roles:
    - role: webserver
      when: inventory_hostname in groups['webservers']
    - role: database
      when: inventory_hostname in groups['dbservers']

Role Dependencies

Declaring Dependencies

# meta/main.yml
dependencies:
  - role: common
    vars:
      version: 1.0.0
  - role: security
    vars:
      level: high

Managing Dependencies

# requirements.yml
---
- src: https://github.com/company/ansible-common
  name: common
  version: v1.0.0

- src: https://github.com/company/ansible-security
  name: security
  version: master

Role Variables

Variable Precedence

# Group variables
group_vars/all.yml:
  nginx_port: 80

# Role defaults
roles/webserver/defaults/main.yml:
  nginx_port: 8080

# Role variables
roles/webserver/vars/main.yml:
  ssl_cert_path: /etc/ssl/certs

# Playbook variables
- hosts: webservers
  vars:
    nginx_port: 443

Best Practices

Role Organization

# tasks/main.yml
---
- name: Include OS-specific variables
  include_vars: "{{ ansible_os_family }}.yml"

- import_tasks: preflight.yml
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: hardening.yml
- import_tasks: monitoring.yml

Testing

molecule/default/converge.yml

---
- name: Converge
  hosts: all
  tasks:
    - name: Include webserver role
      include_role:
        name: webserver

molecule/default/verify.yml

---
- name: Verify
  hosts: all
  tasks:
    - name: Check if nginx is running
      command: systemctl status nginx
      register: nginx_status
      failed_when: nginx_status.rc != 0

Advanced Usage

Dynamic Includes

# tasks/main.yml
---
- name: OS-specific setup
  include_tasks: "{{ ansible_os_family | lower }}/setup.yml"

- name: Feature-specific tasks
  include_tasks: "features/{{ feature_name }}.yml"
  when: feature_name is defined

Why This Matters

Roles are the unit of reuse in Ansible. A cleanly structured role with sane defaults, clear variables, and tests accelerates delivery and avoids copy/paste automation.

Common Pitfalls

  • Putting secrets in role vars instead of using Vault or external vars.
  • Overusing role vars (high precedence) instead of defaults (meant to be overridden).
  • Monolithic tasks/main.yml without breaking into logical files.
  • No Molecule tests, making upgrades risky.

Quick Checklist

  • Role has defaults/ with documented, safe defaults.
  • Handlers exist for services touched by the role.
  • OS-specific vars or tasks are included conditionally.
  • Meta declares supported platforms and dependencies.
  • Molecule scenario covers at least Ubuntu 22.04/24.04.

Next Steps

  • Publish to Galaxy or your internal registry with proper meta/.
  • Add CI to run Molecule on PRs.
  • Provide an example playbook and vars in the role README.