Роли Ansible: layout, defaults, handlers и production-ready шаблонизация
Как правильно структурировать роли Ansible. Разбираем layout, разницу между defaults и vars, работу handlers и безопасную шаблонизацию.
title: «Роли Ansible: layout, defaults, handlers и production-ready шаблонизация»
date: 2026-10-11T06:50:00Z
status: published
categories: [«Системное администрирование»]
tags: [«ansible», «roles», «layout», «defaults», «vars», «handlers», «templating», «dependencies», «testing»]
excerpt: «Как писать роли, которые легко переиспользовать и не страшно передавать команде. Полный гайд: layout, defaults vs vars, handlers, зависимости и тестирование.»
readingMinutes: 5
featuredImage: «/images/ansible-role-architecture.png»
Роли Ansible: production-ready layout и управление переменными
Роль — это атом инфраструктуры. Хорошо написанная роль переиспользуется годами, плохо написанная — приносит хаос. Разбираем, как структурировать роли для production.
1. Layout: стандартная структура
roles/nginx/
├── defaults/
│ └── main.yml # 'Ручки', легко переопределить
├── vars/
│ └── main.yml # Политики, переопределить сложно
├── tasks/
│ ├── main.yml
│ ├── setup.yml
│ └── config.yml
├── handlers/
│ └── main.yml
├── templates/
│ ├── nginx.conf.j2
│ └── vhost.conf.j2
├── files/
│ └── static-site.tar.gz
├── meta/
│ └── main.yml # Зависимости
├── tests/
│ ├── inventory
│ ├── test.yml
│ └── verify.yml
└── README.md
Правило: Никаких задач в tasks/main.yml. Только импорты:
# roles/nginx/tasks/main.yml
- import_tasks: setup.yml
- import_tasks: config.yml
2. defaults vs vars: золотое правило
| Файл | Приоритет | Что хранить |
|---|---|---|
defaults/main.yml |
Самый низкий | «Ручки» (tunable knobs): порты, версии, флаги |
vars/main.yml |
Высокий | Политики: пути, имена пакетов, жёсткие константы |
Пример defaults/main.yml:
nginx_version: "1.24"
nginx_worker_processes: auto
nginx_client_max_body_size: 10m
use_ssl: true
Пример vars/main.yml:
nginx_user: nginx
nginx_group: nginx
nginx_conf_dir: /etc/nginx
nginx_pid_file: /run/nginx.pid
Почему так?
Пользователь роли должен легко поменять версию (nginx_version: "1.26"), но не должен случайно сломать путь к конфигам.
3. Handlers: группировка и listen
# roles/nginx/tasks/config.yml
- name: Deploy main config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reload nginx
- name: Deploy vhost
template:
src: vhost.conf.j2
dest: /etc/nginx/conf.d/app.conf
notify: Reload nginx
# roles/nginx/handlers/main.yml
- name: Reload nginx
listen: "web services" # Группировка
ansible.builtin.service:
name: nginx
state: reloaded
Группировка через listen:
Другие роли тоже могут уведомить web services:
# roles/app/handlers/main.yml
- name: Restart php-fpm
listen: "web services"
ansible.builtin.service:
name: php-fpm
state: restarted
Теперь один notify перезапустит и nginx, и php-fpm.
4. Шаблоны: Jinja2 best practices
Используйте значения по умолчанию в шаблонах:
worker_processes {{ nginx_worker_processes | default('auto') }};
pid {{ nginx_pid_file | default('/run/nginx.pid') }};
Для статики — copy, для конфигов — template:
# Статика (не рендерится)
- name: Deploy static assets
copy:
src: static-site.tar.gz
dest: /var/www/
# Конфиг (рендерится Jinja2)
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
Lookup-помощники:
- name: Deploy from template string
ansible.builtin.copy:
content: "{{ lookup('template', 'templates/inline.conf.j2') }}"
dest: /etc/app/inline.conf
5. Зависимости: meta/main.yml
Если вашей роли нужен postgresql:
# roles/nginx/meta/main.yml
dependencies:
- role: postgresql
vars:
postgresql_version: "15"
postgresql_shared_buffers: "256MB"
Галактика (requirements.yml):
# requirements.yml
roles:
- name: geerlingguy.nginx
version: "4.0.0"
- name: geerlingguy.php
version: "3.5.0"
Установка:
ansible-galaxy install -r requirements.yml
6. Тестирование роли (Molecule)
molecule.yml:
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ubuntu:22.04
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
lint: |
yamllint .
ansible-lint
verify.yml:
- name: Verify
hosts: all
tasks:
- name: Check nginx is running
ansible.builtin.service:
name: nginx
state: started
- name: Check port 80
ansible.builtin.wait_for:
port: 80
7. Precedence (приоритеты) — памятка
От высшего к низшему:
--extra-vars(CLI)- Play vars / vars_prompt
- Block vars
- Role vars (
vars/main.yml) - Role defaults (
defaults/main.yml) - Inventory group_vars/host_vars
- Facts
Практика: Держите «ручки» в defaults, политики — в vars. Секреты — вне VCS (Vault/SOPS).
8. Production-ready чек-лист
- Layout:
defaults/,vars/,tasks/(с импортами),handlers/,templates/,meta/. - В
defaults/только «ручки», вvars/только политики. - Handlers сгруппированы через
listen. - Зависимости прописаны в
meta/main.yml. - Есть
requirements.ymlдля galaxy-ролей. - Роль покрыта Molecule тестами (converge + verify).
- Шаблоны используют
| default(). - Документация всех переменных в
defaults/main.yml. - Нет
command/shellбезcreates/removes.