Ansible с нуля: от первого плейбука до управления парком серверов
Семёнов Евгений Сергеевич, директор АйТи Фреш. Ansible — самый удобный инструмент автоматизации из тех, что я использовал за 15 лет. Не требует агента на клиентах, работает через штатный SSH, конфигурируется понятным YAML. Любому системному администратору достаточно трёх рабочих вечеров, чтобы научиться писать плейбуки, которые накатывают типовую настройку на 50 серверов за пять минут вместо трёх рабочих дней кликанья в putty. Разберём весь путь на реальных примерах.
Что такое Ansible и чем он отличается от аналогов
Ansible — push-модель автоматизации на Python. С управляющей машины по SSH запускаются задачи на целевых серверах, Python-модули собираются и копируются во временный каталог, исполняются, результат возвращается. Никаких агентов, никаких отдельных портов — только стандартный SSH (Linux) или WinRM (Windows).
| Инструмент | Модель | Агент | Язык |
|---|---|---|---|
| Ansible | Push | Нет | YAML + Jinja2 |
| Puppet | Pull | Да | DSL на Ruby |
| Chef | Pull | Да | Ruby DSL |
| SaltStack | Push/Pull | Да (minion) | YAML + Jinja2 |
Установка на управляющей машине
Для начала — рабочая станция или небольшая виртуалка с Debian/Ubuntu или AlmaLinux. Я ставлю на ноутбук и на bastion-хост в дата-центре МТС Москва — чтобы можно было запускать и из офиса, и с любого места через bastion.
# Debian 12
apt update
apt install -y ansible ansible-lint python3-pip sshpass
pip3 install --user pywinrm pyvmomi
# AlmaLinux 9
dnf install -y epel-release
dnf install -y ansible-core ansible-collection-ansible-posix
# Проверка
ansible --version
ansible localhost -m ping
Inventory — список ваших хостов
Inventory — файл, описывающий серверы и их группы. Минимальный вариант — /etc/ansible/hosts:
[webservers]
web01.corp.example.ru
web02.corp.example.ru
web03.corp.example.ru
[dbservers]
db01.corp.example.ru
db02.corp.example.ru
[backup]
backup.corp.example.ru
[linux:children]
webservers
dbservers
backup
[windows]
dc01.corp.example.ru
dc02.corp.example.ru
[windows:vars]
ansible_connection=winrm
ansible_user=ansible@CORP.EXAMPLE.RU
ansible_winrm_transport=kerberos
ansible_winrm_server_cert_validation=ignore
На больших инфраструктурах inventory удобнее держать в YAML и разбивать по папкам:
inventory/
├── production/
│ ├── hosts.yml
│ ├── group_vars/
│ │ ├── all.yml
│ │ ├── webservers.yml
│ │ └── dbservers.yml
│ └── host_vars/
│ ├── web01.yml
│ └── db01.yml
└── staging/
└── hosts.yml
Первый плейбук
Плейбук — YAML-файл со списком задач. Начнём с самого простого — установим nginx на группу webservers:
# nginx-install.yml
---
- name: Базовая установка nginx
hosts: webservers
become: true
vars:
nginx_worker_processes: auto
tasks:
- name: Установка nginx
apt:
name: nginx
state: present
update_cache: true
- name: Запуск и автозагрузка
systemd:
name: nginx
state: started
enabled: true
- name: Копирование конфига
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
backup: true
notify: reload nginx
handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded
Запуск:
ansible-playbook -i inventory/production/hosts.yml nginx-install.yml
# Dry-run перед реальным запуском
ansible-playbook -i inventory/production/hosts.yml nginx-install.yml --check --diff
# Только на одном хосте
ansible-playbook -i inventory/production/hosts.yml nginx-install.yml --limit web01
Идемпотентность — ключевое свойство
Идемпотентный код можно запускать сколько угодно раз — результат не изменится. Это значит, если пакет уже установлен, модуль apt его не трогает; если конфиг совпадает, template не перезаписывает. В выводе Ansible видно, что changed=0 — ничего не поменялось.
Я всегда запускаю свежий плейбук два раза подряд. Первый раз — changes=N, второй раз — changes=0. Если во второй раз есть изменения, значит где-то не идемпотентность: обычно это забытое creates: у команды command: или отсутствие when:.
Роли — переиспользуемые модули
Роль — стандартизированная структура каталогов:
roles/
└── nginx/
├── defaults/
│ └── main.yml
├── handlers/
│ └── main.yml
├── meta/
│ └── main.yml
├── tasks/
│ └── main.yml
├── templates/
│ └── nginx.conf.j2
└── vars/
└── main.yml
После создания роли плейбук пишется в одну строчку:
- hosts: webservers
become: true
roles:
- nginx
- common
- monitoring
Собственные роли храним в Git, общие ставим через ansible-galaxy install.
Jinja2-шаблоны
Любой конфиг с переменными — шаблон Jinja2. Пример фрагмента nginx.conf.j2:
worker_processes {{ nginx_worker_processes | default('auto') }};
worker_connections {{ nginx_worker_connections | default(1024) }};
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.port }};
server_name {{ vhost.server_name }};
root /var/www/{{ vhost.name }};
{% if vhost.ssl | default(false) %}
ssl_certificate /etc/ssl/{{ vhost.name }}.crt;
ssl_certificate_key /etc/ssl/{{ vhost.name }}.key;
{% endif %}
}
{% endfor %}
Ansible Vault для секретов
# Шифрование файла
ansible-vault encrypt group_vars/production/secrets.yml
# Правка зашифрованного
ansible-vault edit group_vars/production/secrets.yml
# Запуск с vault-паролем
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
В CI/CD передаю vault-password через переменную окружения, которая берётся из Secrets Manager.
Windows через WinRM
На целевой Windows-машине заранее настраиваем WinRM. Я пользуюсь стандартным скриптом с GitHub ansible-windows:
# На Windows от имени администратора
Invoke-WebRequest -Uri `
"https://raw.githubusercontent.com/ansible/ansible-documentation/stable-2.16/examples/scripts/ConfigureRemotingForAnsible.ps1" `
-OutFile ConfigureRemotingForAnsible.ps1
.\ConfigureRemotingForAnsible.ps1 -CertValidityDays 3650
Простейший плейбук для Windows:
---
- hosts: windows
gather_facts: false
tasks:
- name: Создание локальной группы
ansible.windows.win_group:
name: DBAdmins
state: present
- name: Установка Chrome через Chocolatey
chocolatey.chocolatey.win_chocolatey:
name: googlechrome
state: present
Реальный кейс: накатка стандарта на 60 серверов
В сентябре 2024 клиент — логистическая компания в Подольске — попросил привести 60 Ubuntu-серверов к единому состоянию: одинаковый набор пакетов, пользователи, sudoers, nrpe для Nagios, rsyslog на центральный лог-сервер, timezone, NTP, swappiness. До Ansible это делалось вручную при установке каждого сервера, расхождения набегали в стороны.
Собрали роль baseline на 28 задач. Плейбук запускали пачками по 10 серверов (serial: 10). Сухой прогон — 340 changes. Боевой прогон — 5 минут 40 секунд на пачку, итого 35 минут на все 60 серверов. Повторный запуск — 0 changes. С тех пор этот плейбук гоняется еженедельно из GitLab CI, любой дрейф виден в отчёте.
Бюджет проекта — 95 000 руб. за настройку + плейбук, и сейчас экономит клиенту порядка 18 часов админской работы в месяц. Инфраструктура разместилась на 3 Dell Xeon Platinum 8280 в нашем дата-центре, Mellanox 40G между нодами.
Советы из практики
- Всегда --check --diff перед реальным запуском на проде.
- Теги на задачах (
tags: nginx) — ускоряют частичный прогон. - Версии collections и ролей пинните (requirements.yml с конкретными версиями).
- Линтер ansible-lint в pre-commit hook — ловит типовые ошибки до коммита.
- Не более 50 задач в одном плейбуке — делите на роли.
- Ограничивайте serial на критичных группах — не убить все prod-сервера сразу при ошибке.
Автоматизируем вашу инфраструктуру
Пишу Ansible-роли под ваши задачи, настраиваю GitLab CI с автопрогоном плейбуков, обучаю вашу IT-команду. Первый базовый плейбук — за один рабочий день, полный переход на IaC — 2-4 недели в зависимости от размера парка. Сопровождение инфраструктуры на абонентской основе.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы по Ansible
- Нужен ли Ansible, если серверов 5-10?
- Да, окупается даже на 3-5 серверах. Главное — не выигрыш во времени на одной задаче, а повторяемость и документированный процесс.
- Ansible работает с Windows?
- Да, через WinRM с HTTPS или Kerberos. Есть сотни ansible.windows модулей для PowerShell-задач.
- В чём разница между playbook и role?
- Playbook — верхнеуровневый сценарий. Role — переиспользуемый модуль с задачами, шаблонами, переменными в стандартной структуре каталогов.
- Что такое идемпотентность и зачем она?
- Многократный запуск даёт одинаковый результат. Ключевое свойство Ansible — плейбук можно запускать хоть каждый час без побочных эффектов.
- Как безопасно хранить пароли в плейбуках?
- Через ansible-vault: шифруется файл паролем или ключом. В CI/CD обычно HashiCorp Vault или AWS Secrets Manager через plugin lookup.