· 17 мин чтения

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

Семёнов Евгений Сергеевич, директор АйТи Фреш. Ansible — самый удобный инструмент автоматизации из тех, что я использовал за 15 лет. Не требует агента на клиентах, работает через штатный SSH, конфигурируется понятным YAML. Любому системному администратору достаточно трёх рабочих вечеров, чтобы научиться писать плейбуки, которые накатывают типовую настройку на 50 серверов за пять минут вместо трёх рабочих дней кликанья в putty. Разберём весь путь на реальных примерах.

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

Ansible — push-модель автоматизации на Python. С управляющей машины по 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

Идемпотентность — ключевое свойство

Идемпотентный код можно запускать сколько угодно раз — результат не изменится. Это значит, если пакет уже установлен, модуль 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 подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.