W skrócie: Ansible Roles to standardowy sposób organizacji playbooków w Ansible – dzielą kod na tasks, handlers, templates, files, vars i defaults, dzięki czemu automatyzacja jest czytelna, wielokrotnego użytku i łatwa do utrzymania w dużych projektach infrastruktury.
Spis treści
- Dlaczego zwykłe playbooki przestają wystarczać
- Czym jest Ansible Role
- Struktura katalogów roli krok po kroku
- Jak stworzyć rolę – ansible-galaxy init
- Używanie ról w playbooku
- Zmienne w rolach: defaults vs vars
- Handlers w rolach
- Zależności między rolami (meta/main.yml)
- Organizacja dużego projektu Ansible
- Ansible Galaxy i Collections – współdzielenie ról
- Testowanie ról – Molecule
- Najczęstsze błędy przy pracy z rolami
- Dobre praktyki – checklista
- FAQ – najczęstsze pytania o Ansible Roles
- Podsumowanie
1. Dlaczego zwykłe playbooki przestają wystarczać
Na początku przygody z Ansible większość osób pisze wszystko w jednym pliku playbook.yml. Działa to świetnie, dopóki playbook obsługuje jeden serwer i kilka zadań. Problem pojawia się, gdy trzeba:
- skonfigurować 5 różnych typów serwerów (web, db, load balancer, cache, monitoring),
- powtórzyć te same zadania w kilku projektach,
- utrzymać spójność między środowiskami
dev,stagingiproduction, - wdrożyć zmianę bez przeglądania 800-liniowego pliku YAML.
Bez struktury playbooki zamieniają się w tzw. „YAML spaghetti” – kod trudny do czytania, testowania i debugowania. Rozwiązaniem tego problemu w Ansible są role.
2. Czym jest Ansible Role
Ansible Role to samodzielna, przenośna jednostka automatyzacji, która grupuje zadania (tasks), zmienne (vars), pliki (files), szablony (templates) i handlery dotyczące jednej, konkretnej funkcji – np. instalacji Nginx, konfiguracji firewalla czy wdrożenia aplikacji.
Rola to w praktyce narzucona konwencja katalogów, którą Ansible automatycznie rozpoznaje i wczytuje – bez konieczności ręcznego wskazywania ścieżek do plików w każdym zadaniu.
Główne korzyści z użycia ról:
- Reużywalność – ta sama rola
nginxdziała na dev, staging i produkcji. - Czytelność – playbook główny staje się listą ról, a nie stroną kodu.
- Modularność – każdą rolę można rozwijać, testować i wersjonować osobno.
- Współdzielenie – gotowe role można pobrać z Ansible Galaxy zamiast pisać od zera.
3. Struktura katalogów roli krok po kroku
Standardowa rola ma następującą strukturę:
roles/
└── nginx/
├── defaults/
│ └── main.yml # domyślne zmienne (najniższy priorytet)
├── files/
│ └── nginx.conf # statyczne pliki kopiowane na hosty
├── handlers/
│ └── main.yml # handlery, np. restart usługi
├── meta/
│ └── main.yml # metadane, zależności, autor, licencja
├── tasks/
│ └── main.yml # główna lista zadań roli
├── templates/
│ └── nginx.conf.j2 # szablony Jinja2
├── vars/
│ └── main.yml # zmienne o wyższym priorytecie
└── README.md # dokumentacja roli
Co ważne – żaden z tych katalogów nie jest obowiązkowy. Jeśli rola nie potrzebuje handlerów, po prostu pomija się katalog handlers/. Ansible sam wykrywa, które elementy istnieją.
Znaczenie poszczególnych katalogów
| Katalog | Do czego służy | Przykład użycia |
|---|---|---|
tasks/ | Lista zadań wykonywanych przez rolę | instalacja pakietu, uruchomienie usługi |
handlers/ | Zadania uruchamiane przez notify | restart Nginx po zmianie konfiguracji |
templates/ | Pliki Jinja2 (.j2) generowane dynamicznie | nginx.conf.j2 z podstawianymi zmiennymi |
files/ | Statyczne pliki kopiowane bez zmian | certyfikaty, skrypty, binaria |
vars/ | Zmienne „sztywne”, trudne do nadpisania | stałe wartości specyficzne dla roli |
defaults/ | Zmienne domyślne, łatwe do nadpisania | porty, wersje, ścieżki konfigurowalne |
meta/ | Zależności od innych ról, metadane Galaxy | dependencies: [common, firewall] |
4. Jak stworzyć rolę – ansible-galaxy init
Nie trzeba tworzyć struktury katalogów ręcznie. Ansible dostarcza do tego narzędzie ansible-galaxy:
mkdir roles
cd roles
ansible-galaxy init nginx
Polecenie to wygeneruje kompletny szkielet roli nginx ze wszystkimi katalogami i pustymi plikami main.yml. To najszybszy i zalecany sposób startu z nową rolą.
Przykładowa zawartość roles/nginx/tasks/main.yml:
---
- name: Zainstaluj Nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Wgraj konfigurację Nginx
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
notify: Restart nginx
- name: Upewnij się, że Nginx działa i jest włączony
ansible.builtin.service:
name: nginx
state: started
enabled: true
5. Używanie ról w playbooku
Gdy rola jest gotowa, główny playbook staje się bardzo czytelny – wygląda jak lista funkcji do wywołania:
---
- name: Konfiguracja serwerów webowych
hosts: webservers
become: true
roles:
- common
- nginx
- { role: firewall, allowed_ports: [80, 443] }
Można też jawnie kontrolować kolejność wykonania ról względem innych zadań, używając słowa kluczowego tasks z modułem include_role lub import_role:
tasks:
- name: Uruchom rolę nginx warunkowo
ansible.builtin.include_role:
name: nginx
when: ansible_facts['os_family'] == "Debian"
Różnica import_role vs include_role: import_role jest wczytywana statycznie w momencie parsowania playbooka (nie obsługuje pętli), a include_role jest wczytywana dynamicznie w czasie wykonania (obsługuje when, loop per-task).
6. Zmienne w rolach: defaults vs vars
To jeden z najczęściej mylonych elementów w Ansible. Kluczowa zasada dotyczy priorytetu zmiennych:
defaults/main.yml→ najniższy priorytet w całym Ansible. Można je łatwo nadpisać z playbooka, inventory czygroup_vars.vars/main.yml→ wysoki priorytet, trudniejszy do nadpisania z zewnątrz roli. Używane do wartości, które nie powinny być zmieniane przez użytkownika roli.
Przykład – defaults/main.yml:
---
nginx_port: 80
nginx_worker_processes: auto
nginx_user: www-data
Dzięki temu w playbooku można łatwo nadpisać port bez modyfikowania samej roli:
roles:
- role: nginx
nginx_port: 8080
7. Handlers w rolach
Handlery to zadania wywoływane tylko wtedy, gdy inne zadanie zgłosi zmianę (notify), i uruchamiane raz, na końcu wykonania playbooka (nawet jeśli notify wystąpi kilka razy).
handlers/main.yml:
---
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Dzięki temu usługa restartuje się tylko wtedy, gdy faktycznie zmieniła się konfiguracja – a nie przy każdym uruchomieniu playbooka.
8. Zależności między rolami (meta/main.yml)
Plik meta/main.yml pozwala zadeklarować, że dana rola wymaga innej roli do poprawnego działania:
---
dependencies:
- role: common
- role: firewall
allowed_ports: [80, 443]
galaxy_info:
author: twoja-firma
description: Instalacja i konfiguracja Nginx
license: MIT
min_ansible_version: "2.15"
platforms:
- name: Ubuntu
versions: [22.04, 24.04]
Zależności zdefiniowane w meta/main.yml są uruchamiane automatycznie przed zadaniami roli macierzystej.
9. Organizacja dużego projektu Ansible
Dla większych projektów rekomendowana struktura wygląda tak:
inventories/
├── production/
│ ├── hosts.yml
│ └── group_vars/
│ ├── all.yml
│ └── webservers.yml
└── staging/
├── hosts.yml
└── group_vars/
└── all.yml
roles/
├── common/
├── nginx/
├── postgresql/
└── monitoring/
playbooks/
├── site.yml
├── deploy-web.yml
└── deploy-db.yml
ansible.cfg
requirements.yml
Kluczowe zasady tej organizacji:
- Jedna rola = jedna odpowiedzialność (zasada podobna do Single Responsibility Principle).
group_varsihost_varstrzymają konfigurację specyficzną dla środowiska, a nie dla roli – dzięki temu ta sama rola działa identycznie na dev i produkcji, różnią się tylko wartości zmiennych.site.ymljako główny playbook agreguje pozostałe playbooki przezimport_playbook.requirements.ymldefiniuje zewnętrzne role i kolekcje pobierane z Ansible Galaxy.
10. Ansible Galaxy i Collections – współdzielenie ról
Ansible Galaxy to publiczne repozytorium gotowych ról i kolekcji. Zamiast pisać rolę do instalacji Dockera czy PostgreSQL od zera, można ją pobrać:
ansible-galaxy install geerlingguy.docker
Lub zdefiniować wszystkie zależności projektu w requirements.yml:
---
roles:
- name: geerlingguy.docker
version: "7.1.0"
collections:
- name: community.general
- name: ansible.posix
I zainstalować je jednym poleceniem:
ansible-galaxy install -r requirements.yml
Collections to nowocześniejszy, szerszy format dystrybucji niż same role – mogą zawierać role, moduły, pluginy i dokumentację w jednym pakiecie. Od Ansible 2.10+ większość modułów (poza ansible.builtin) pochodzi właśnie z kolekcji.
11. Testowanie ról – Molecule
Dobra praktyka przy pisaniu ról produkcyjnych to ich automatyczne testowanie za pomocą Molecule – frameworka do testowania ról w izolowanych kontenerach lub maszynach wirtualnych.
pip install molecule molecule-plugins[docker] --break-system-packages
cd roles/nginx
molecule init scenario
molecule test
Molecule automatycznie: tworzy środowisko testowe, uruchamia rolę, sprawdza, czy można ją uruchomić ponownie bez wprowadzania dodatkowych zmian (tzw. idempotencja), a następnie usuwa środowisko testowe po zakończeniu testów.
12. Najczęstsze błędy przy pracy z rolami
- Trzymanie wszystkiego w
vars/zamiastdefaults/– utrudnia to nadpisywanie zmiennych z zewnątrz. - Brak
become: truetam, gdzie jest potrzebny – zadania wymagające uprawnień root nie zadziałają. - Twarde kodowanie wartości w
tasks/main.ymlzamiast wyciągnięcia ich do zmiennych. - Zbyt duże, „monolityczne” role obsługujące kilka niepowiązanych funkcji naraz – lepiej podzielić na mniejsze role.
- Brak tagów (
tags:) – utrudnia uruchamianie tylko wybranej części roli podczas debugowania. - Ignorowanie idempotentności – rola, która przy drugim uruchomieniu zgłasza zmiany, prawdopodobnie ma błąd logiczny.
13. Dobre praktyki – checklista
- [ ] Każda rola ma jedną, jasno określoną odpowiedzialność.
- [ ] Zmienne konfigurowalne trafiają do
defaults/main.yml. - [ ] Rola posiada
README.mdz opisem zmiennych i przykładem użycia. - [ ] Zależności są jawnie zadeklarowane w
meta/main.yml. - [ ] Wrażliwe dane (hasła, klucze) są szyfrowane przez
ansible-vault. - [ ] Rola przechodzi test idempotentności (
molecule testlub podwójne uruchomienieansible-playbook). - [ ] Zadania mają nadane
tagsułatwiające selektywne uruchamianie. - [ ] Nazwy zmiennych mają prefiks nazwy roli (np.
nginx_port, nieport), by uniknąć konfliktów.
14. FAQ – najczęstsze pytania o Ansible Roles
Czym różni się rola od playbooka?
Playbook to plik YAML opisujący, co i na jakich hostach ma zostać wykonane. Rola to uporządkowany, wielokrotnego użytku zestaw zadań, zmiennych i plików, który playbook może wywołać. Playbook orkiestruje, rola implementuje logikę.
Czy każda rola musi mieć wszystkie katalogi (tasks, handlers, vars itd.)?
Nie. Wymagany jest w praktyce tylko tasks/main.yml. Pozostałe katalogi dodaje się wyłącznie wtedy, gdy rola faktycznie z nich korzysta.
Jaka jest różnica między defaults a vars w roli?
defaults/main.yml ma najniższy priorytet w Ansible i jest przeznaczony do łatwego nadpisywania. vars/main.yml ma wysoki priorytet i służy do wartości, które nie powinny być modyfikowane przez użytkownika roli.
Jak nadpisać zmienną roli z poziomu playbooka?
Wystarczy podać zmienną bezpośrednio przy wywołaniu roli w sekcji roles: albo umieścić ją w group_vars/host_vars – obie metody nadpisują wartości z defaults/main.yml.
Czym są Ansible Collections i czy zastępują role?
Collections to szerszy format dystrybucji, który może zawierać role, moduły i pluginy razem. Nie zastępują ról – rozszerzają sposób ich pakowania i dystrybucji, szczególnie od Ansible 2.10 wzwyż.
Czy warto pisać własne role, czy korzystać z gotowych z Ansible Galaxy?
Dla popularnych, standardowych zadań (Docker, PostgreSQL, podstawowy hardening) warto korzystać z dojrzałych ról z Galaxy. Własne role warto pisać dla logiki specyficznej dla danej firmy lub aplikacji.
Jak przetestować rolę Ansible przed wdrożeniem na produkcję?
Standardem branżowym jest Molecule – uruchamia rolę w izolowanym kontenerze, weryfikuje wynik i sprawdza idempotentność przy powtórnym uruchomieniu.
Podsumowanie
Ansible Roles to fundament skalowalnej automatyzacji infrastruktury. Zamiast jednego, rosnącego bez końca pliku YAML, otrzymujemy modułowe, przenośne komponenty, które można testować, wersjonować i współdzielić między projektami. Kluczem do sukcesu jest trzymanie się konwencji katalogów (tasks, handlers, templates, defaults, vars, meta), świadome zarządzanie priorytetem zmiennych oraz regularne testowanie idempotentności ról za pomocą narzędzi takich jak Molecule.
Zacznij od ansible-galaxy init, trzymaj się zasady jednej odpowiedzialności na rolę, a Twoje playbooki pozostaną czytelne nawet przy setkach serwerów w środowisku produkcyjnym.

