Ansible с нуля: от первого плейбука до управления парком серверов
Я, Семёнов Евгений Сергеевич, директор АйТи Фреш, за 15 лет в IT повидал всякое. Могу с уверенностью сказать: круче Ansible инструмента для автоматизации я не встречал. Вы только представьте — никаких агентов на клиентских машинах! Он прекрасно общается по обычному SSH, а все настройки делаются на понятном языке YAML. Да что там говорить, любой системный администратор буквально за три рабочих вечера освоит написание плейбуков. А потом? Эти плейбуки способны накатить типовую конфигурацию на целых 50 серверов всего за пять минут! Это же просто космос по сравнению с тремя рабочими днями утомительного кликанья в PuTTY. Хотите узнать, как мы это делаем на абсолютно реальных примерах?
Что такое Ansible и чем он отличается от аналогов
Так вот, как это работает? Ansible построен на Python и использует принцип push-модели. С вашей управляющей машины через 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
Идемпотентность — ключевое свойство
Самое классное в Ansible — это его идемпотентность. Что это значит? Можете запускать код сколько угодно раз — результат не изменится. Если пакет уже установлен, модуль 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`. Это наш must-have! Интегрируйте его прямо в `pre-commit hook`, и он будет ловить типовые ошибки ещё до того, как вы успеете нажать "commit". Согласитесь, гораздо приятнее исправлять мелкие опечатки сразу, чем потом тратить время на ревью или, что хуже, на отладку уже в релизе.
- Одно важное правило, которое мы вынесли из практики: никогда не делайте больше 50 задач в одном плейбуке. Просто подумайте, кто потом будет это читать или, не дай бог, отлаживать? Разбивайте их на логичные `роли`. Это не только повышает читаемость кода, но и значительно упрощает дальнейшую поддержку и повторное использование.
- Представьте, что одна ошибка может положить все ваши `prod-сервера` за секунды. Страшно? Вот почему мы настоятельно советуем ограничивать `serial` на `критичных группах` серверов. Это простая, но мощная страховка: вместо того чтобы раскатывать изменения сразу на все машины, `serial` делает это постепенно. Если что-то пойдёт не так, вы потеряете лишь часть, а не весь продакшен.
Автоматизируем вашу инфраструктуру
Пишу 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.
