· 17 мин чтения

Ansible с нуля: от первого плейбука до управления парком серверов

Ansible с нуля: от первого плейбука до управления парком серверов

Я, Семёнов Евгений Сергеевич, директор АйТи Фреш, за 15 лет в IT повидал всякое. Могу с уверенностью сказать: круче Ansible инструмента для автоматизации я не встречал. Вы только представьте — никаких агентов на клиентских машинах! Он прекрасно общается по обычному SSH, а все настройки делаются на понятном языке YAML. Да что там говорить, любой системный администратор буквально за три рабочих вечера освоит написание плейбуков. А потом? Эти плейбуки способны накатить типовую конфигурацию на целых 50 серверов всего за пять минут! Это же просто космос по сравнению с тремя рабочими днями утомительного кликанья в PuTTY. Хотите узнать, как мы это делаем на абсолютно реальных примерах?

Что такое Ansible и чем он отличается от аналогов

Так вот, как это работает? Ansible построен на Python и использует принцип push-модели. С вашей управляющей машины через SSH отправляются задачи прямиком на целевые серверы. Там Python-модули собираются, копируются во временную папку, исполняются и, конечно, возвращают нам результат. А самое классное? Никаких лишних агентов и никаких открытых портов! Нужен только стандартный SSH, если вы работаете с Linux, или WinRM для Windows.

ИнструментМодельАгентЯзык
AnsiblePushНетYAML + Jinja2
PuppetPullДаDSL на Ruby
ChefPullДаRuby DSL
SaltStackPush/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 между нодами. Серьёзная связка, не так ли?

Советы из практики

Автоматизируем вашу инфраструктуру

Пишу 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.

Подпишитесь на рассылку ITfresh

И это ещё не всё! Раз в неделю мы делимся практическими гайдами для руководителей IT-отделов и системных администраторов. Чего ждать? Всё самое важное: от безопасности и работы с 1С до миграций, резервных копий и, конечно, лайфхаков из наших реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.