1. Why roles? #
Reuse, test and share.
From a monolithic playbook to a role #
A growing playbook becomes unreadable. A role groups everything related to a component (installation, configuration, service) in a standardized structure: it can be reused across projects, tested independently and shared through Ansible Galaxy.
tasks/main.yml is mandatory.Creating the directory layout #
mkdir -p roles && cd roles
ansible-galaxy role init nginx
tree nginx
nginx/
├── README.md
├── defaults/main.yml # variables par défaut (priorité la plus basse)
├── files/ # fichiers copiés tels quels
├── handlers/main.yml # actions déclenchées par notify
├── meta/main.yml # métadonnées et dépendances
├── tasks/main.yml # point d'entrée du rôle
├── templates/ # fichiers Jinja2 (.j2)
├── tests/ # inventaire et playbook de test
└── vars/main.yml # variables internes (priorité élevée)2. Writing a complete role: nginx #
Tasks, defaults, templates and handlers.
defaults and tasks #
# roles/nginx/defaults/main.yml
nginx_port: 80
nginx_server_name: "{{ ansible_fqdn }}"
nginx_worker_processes: auto
nginx_enable_service: true# roles/nginx/tasks/main.yml
- name: Installer nginx
ansible.builtin.package:
name: nginx
state: present
- name: Déployer la configuration du site
ansible.builtin.template:
src: site.conf.j2
dest: /etc/nginx/conf.d/site.conf
owner: root
mode: "0644"
validate: nginx -t -c /etc/nginx/nginx.conf
notify: Recharger nginx
- name: Démarrer et activer nginx
ansible.builtin.service:
name: nginx
state: started
enabled: "{{ nginx_enable_service }}" Template and handler #
# roles/nginx/templates/site.conf.j2
server {
listen {{ nginx_port }};
server_name {{ nginx_server_name }};
root /var/www/{{ nginx_server_name }};
access_log /var/log/nginx/{{ nginx_server_name }}.access.log;
}# roles/nginx/handlers/main.yml
- name: Recharger nginx
ansible.builtin.service:
name: nginx
state: reloadedGood to know: A handler runs only once, at the end of the play, and only if a task that notifies it actually changed something. Force it to run immediately with - meta: flush_handlers.3. Using a role #
In a playbook, with its variables.
Calling the role #
# site.yml
- hosts: webservers
become: true
roles:
- role: nginx
vars:
nginx_port: 8080
- role: monitoring_agent
tags: [monitoring]ansible-playbook -i inventories/lab/hosts.ini site.yml
ansible-playbook site.yml --tags monitoring
ansible-playbook site.yml --list-tasksYou can also call it dynamically in the middle of a task list with include_role (conditional or looped execution) or import_role (static inclusion):
tasks:
- name: Installer le serveur web
ansible.builtin.include_role:
name: nginx
when: ansible_os_family == "Debian" Dependencies between roles #
# roles/wordpress/meta/main.yml
dependencies:
- role: nginx
vars: { nginx_port: 80 }
- role: mariadb4. Sharing with Ansible Galaxy and collections #
Don't reinvent the wheel.
Installing roles and collections #
ansible-galaxy role search nginx --author geerlingguy
ansible-galaxy role install geerlingguy.docker
ansible-galaxy collection install community.general ansible.posix
# Versionner les dépendances du projet
cat requirements.yml
roles:
- name: geerlingguy.docker
version: 7.4.1
collections:
- name: community.general
version: ">=9.0.0"
ansible-galaxy install -r requirements.ymlBest practices #
- One role = one responsibility; name it after the component (
nginx,postgres). - Prefix all variables with the role name (
nginx_port) to avoid collisions. - Put modifiable values in
defaults/and reservevars/for internal constants. - Make every task idempotent and test it with Molecule (see « Going further »).
Common mistake: Avoid writing a monster role that installs, configures and monitors ten components: it becomes impossible to test and reuse.
My progress
Sign in to track your progress and take notes. Sign in
💬 Questions about this lesson
No questions yet: be the first to ask for help or share your configuration.
Course Glossary
Ansible
An open source IT automation tool (IaC) enabling configuration management, application deployment, and orchestration, operating agentlessly via SSH.
Recommended Articles
Ansible: managing your infrastructure with playbooks (Infrastructure as Code)
Write production playbooks: project structure, plays, handlers, tags, serial strategy, error hand...
Ansible best practices: structure, idempotence, security and quality
Ansible best practices: project organization, naming, FQCN, idempotence, modules rather than shel...
Ansible: generating dynamic files with Jinja2 and facts
Create dynamic configuration files: Jinja2 templates, variables, facts, filters, loops, condition...
Ansible: going further (testing, quality, CI/CD and performance)
Industrialize Ansible: ansible-lint, yamllint, Molecule, continuous integration, collections, exe...
Automation and infrastructure as code for Elasticsearch: API, Terraform, Ansible and CI/CD
Automate Elasticsearch administration: REST API and clients, the elasticstack Terraform provider ...
Ansible: driving your automations with a graphical interface (AWX, Semaphore, AAP)
Compare and install Ansible's graphical interfaces: AWX, Ansible Automation Platform, Semaphore a...
Ansible: the inventory (static, dynamic, groups and variables)
Understand and master the Ansible inventory: INI and YAML files, groups, host and group variables...
Ansible: managing security (Vault, SSH, privileges and secrets)
Securing Ansible: Ansible Vault, SSH key authentication, become and sudo, no_log, hardening the c...
Ansible: ad-hoc commands
Run immediate actions on a fleet of servers with ansible: the ping, command, shell, copy, apt, se...