Roles are how you organize Ansible code for reuse. Instead of one massive playbook, you build modular, testable units that compose into complete system configurations.
Role Directory Structure
roles/
nginx/
defaults/ # Default variables (lowest priority)
main.yml
vars/ # Role variables (higher priority)
main.yml
tasks/ # Task files
main.yml
configure.yml
install.yml
handlers/ # Event handlers
main.yml
templates/ # Jinja2 templates
nginx.conf.j2
vhost.conf.j2
files/ # Static files
index.html
meta/ # Role metadata and dependencies
main.yml
tests/ # Test playbooks
test.ymlBuilding a Role
defaults/main.yml
---
nginx_port: 80
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_server_name: localhost
nginx_document_root: /var/www/html
nginx_ssl_enabled: false
nginx_ssl_certificate: ""
nginx_ssl_key: ""
nginx_extra_locations: []tasks/main.yml
---
- name: Include OS-specific variables
include_vars: "{{ ansible_os_family }}.yml"
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: ssl.yml
when: nginx_ssl_enabledtasks/install.yml
---
- name: Install Nginx
package:
name: nginx
state: present
- name: Ensure Nginx is running
service:
name: nginx
state: started
enabled: truetasks/configure.yml
---
- name: Deploy Nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: nginx -t -c %s
notify: Reload Nginx
- name: Deploy virtual host
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: '0644'
notify: Reload Nginx
- name: Create document root
file:
path: "{{ nginx_document_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'handlers/main.yml
---
- name: Reload Nginx
service:
name: nginx
state: reloaded
- name: Restart Nginx
service:
name: nginx
state: restartedmeta/main.yml
---
galaxy_info:
author: Your Name
description: Install and configure Nginx
license: MIT
min_ansible_version: "2.14"
platforms:
- name: Ubuntu
versions: [jammy, noble]
- name: Debian
versions: [bookworm]
dependencies:
- role: common
- role: firewall
vars:
firewall_allowed_ports:
- "{{ nginx_port }}"Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Using Roles
In a Playbook
---
- hosts: webservers
become: true
roles:
- common
- role: nginx
vars:
nginx_port: 443
nginx_ssl_enabled: true
nginx_ssl_certificate: /etc/ssl/certs/app.pem
nginx_ssl_key: /etc/ssl/private/app.key
- role: app
tags: [app, deploy]With include_role (Dynamic)
- name: Deploy web stack
hosts: webservers
tasks:
- include_role:
name: nginx
when: "'webserver' in group_names"
- include_role:
name: "{{ item }}"
loop:
- monitoring
- loggingAnsible Galaxy
# Install from Galaxy
ansible-galaxy install geerlingguy.docker
ansible-galaxy install geerlingguy.postgresql
# Install from requirements file
ansible-galaxy install -r requirements.yml# requirements.yml
roles:
- name: geerlingguy.docker
version: "7.1.0"
- name: geerlingguy.postgresql
version: "3.5.0"
- name: custom_role
src: git+https://github.com/myorg/ansible-role-custom.git
version: v1.0.0
collections:
- name: community.general
version: ">=8.0.0"
- name: ansible.posixGet weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Testing with Molecule
# Initialize a new role with Molecule
molecule init role my_role --driver-name docker
# Run the full test sequence
molecule test
# Develop iteratively
molecule create # Create test container
molecule converge # Run the role
molecule verify # Run tests
molecule destroy # Clean upmolecule/default/molecule.yml
driver:
name: docker
platforms:
- name: ubuntu-test
image: ubuntu:24.04
pre_build_image: true
command: /lib/systemd/systemd
privileged: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
- name: debian-test
image: debian:bookworm
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansiblemolecule/default/verify.yml
---
- name: Verify Nginx
hosts: all
tasks:
- name: Check Nginx is installed
command: nginx -v
changed_when: false
- name: Check Nginx is running
service_facts:
- name: Assert Nginx service is running
assert:
that:
- "'nginx' in ansible_facts.services"
- "ansible_facts.services['nginx'].state == 'running'"
- name: Check Nginx responds
uri:
url: http://localhost:80
status_code: 200Best Practices
| Practice | Why |
|---|---|
Use defaults/ for all variables | Consumers can override everything |
Keep vars/ for internal constants | Platform-specific values, package names |
| One responsibility per role | nginx role shouldn't configure the app |
| Tag your tasks | --tags deploy for partial runs |
| Validate templates | validate: parameter catches syntax errors |
| Pin Galaxy dependencies | Version lock in requirements.yml |
| Test with Molecule | Catch breakage before production |
Use meta/ dependencies | Auto-install required roles |
What's Next?
Our Ansible Automation in 30 Minutes course covers roles, Galaxy, and testing in hands-on lessons. First lesson is free.
---
Ready to go deeper? Check out our hands-on course: Ansible Quickstart — practical exercises you can follow along on your own machine.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Ansible vs Terraform When to Use
Ansible and Terraform solve different infrastructure problems. Learn when to use each, when to use both together, and how they complement each other.
Ansible Inventory: Static and Dynamic
Master Ansible inventory in INI and YAML formats. Learn host groups, variables, dynamic inventory plugins for AWS and Azure, and patterns for scaling.
Ansible Infrastructure as Code Guide
Use Ansible as your Infrastructure as Code tool. Learn how playbooks define, version, and automate your entire infrastructure.
Ansible Vault: Encrypt Secrets Safely
Learn Ansible Vault to encrypt passwords, API keys, and variables. Covers vault create, edit, encrypt_string, and CI/CD usage.
Ansible Vault Secrets Encryption
Encrypt secrets with Ansible Vault for secure automation. Cover file encryption, string-level vaulting, multi-password setups, and CI/CD pipeline integration.
Ansible vs Terraform vs Puppet Guide
Compare Ansible, Terraform, and Puppet for infrastructure automation. Understand when to use each tool and how they complement each other in modern DevOps.
Explore topics
Browse more articles on the topics covered here.