Представьте себе идеально отлаженный паровоз, который без единого рывка доставляет ваш код из точки разработки в точку назначения. Ansible — это именно такой механизм: agentless-оркестратор, который превращает рутинное управление серверами в слаженную работу паровой машины.
В этой статье мы разберём архитектуру Ansible до последнего винтика, поймём, как устроен его «котёл», и научимся запускать первые плейбуки.
Что такое Ansible?
Ansible — это инструмент управления конфигурациями и оркестрации с открытым исходным кодом, созданный Майклом ДеХааном (автором Cobbler и Func) и ныне развиваемый компанией Red Hat.
Главная философия Ansible — простота и отсутствие агентов. В отличие от Puppet или Chef, вам не нужно устанавливать демон на каждый управляемый сервер. Ansible работает поверх стандартного SSH (на Linux) или WinRM (на Windows), используя Python как «топливо» для выполнения задач.
Ключевые принципы:
- Agentless — никаких демонов на клиентах.
- Idempotent — многократное применение плейбука не ломает систему, если она уже в нужном состоянии.
- Declarative — вы описываете желаемое состояние, а не последовательность команд.
- Push-based — управляющий сервер сам «толкает» конфигурации к узлам.

Архитектура Ansible: из чего состоит паровая машина
Ansible — это не монолит, а набор взаимосвязанных компонентов. Разберём каждый «цилиндр» этого двигателя.
Control Node (Управляющий узел)
Это «кабина машиниста» — сервер или рабочая станция, с которой вы запускаете Ansible. Здесь хранятся:
- Инвентаризационные файлы
- Плейбуки
- Роли
- Шаблоны
- Переменные
Требования:
- ОС: Linux (RHEL, Ubuntu, Debian, CentOS) или macOS
- Python: версия 3.8 или выше
- Установленный Ansible
Windows не может быть Control Node (но может быть управляемым узлом через WinRM).
Managed Nodes (Управляемые узлы)
Это «вагоны», которыми вы управляете. На них должен быть:
- SSH-сервер (для Linux/Unix)
- WinRM (для Windows)
- Python 2.7+ или 3.5+ (для Linux/Unix)
⚡ Важно
Ansible не требует установки специального ПО на managed nodes — достаточно стандартного SSH и Python.
Inventory (Инвентаризация)
Это «расписание движения поездов» — файл, в котором описаны все ваши серверы и их группировка.
Простой инвентарь (/etc/ansible/hosts или inventory.ini):
# Простой список хостов
web1.example.com
web2.example.com
db1.example.com
# Группировка по функциям
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
# Группировка по регионам
[moscow]
web1.example.com
db1.example.com
[piter]
web2.example.com
# Вложенные группы
[russia:children]
moscow
piter
# Переменные для группы
[webservers:vars]
http_port=80
max_requests=200Динамический инвентарь (скрипт на Python, Bash или облачный плагин) позволяет автоматически получать список серверов из AWS, Azure, vSphere и других источников.

Playbooks (Плейбуки)
Это «инструкция по эксплуатации» — YAML-файлы, описывающие желаемое состояние системы.
Пример простого плейбука (deploy_web.yml):
---
- name: Установка и настройка веб-сервера
hosts: webservers
become: yes
vars:
http_port: 80
document_root: /var/www/html
tasks:
- name: Установить пакет nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: yes
when: ansible_os_family == "Debian"
- name: Установить пакет httpd
ansible.builtin.yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"
- name: Создать директорию для сайта
ansible.builtin.file:
path: "{{ document_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Развернуть индексную страницу
ansible.builtin.copy:
content: |
<html>
<head><title>RoadIT Steam Engine</title></head>
<body><h1>Работает на Ansible!</h1></body>
</html>
dest: "{{ document_root }}/index.html"
mode: '0644'
- name: Запустить и включить сервис
ansible.builtin.service:
name: "{{ 'nginx' if ansible_os_family == 'Debian' else 'httpd' }}"
state: started
enabled: yes
- name: Открыть порт в фаерволе
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: "{{ http_port }}"
jump: ACCEPT
comment: "Allow HTTP traffic"Modules (Модули)
Это «инструменты в ящике инженера» — готовые функции для выполнения конкретных задач. Ansible поставляется с тысячами модулей:
- ansible.builtin.apt/yum/dnf — управление пакетами
- ansible.builtin.copy/template — работа с файлами
- ansible.builtin.service/systemd — управление сервисами
- ansible.builtin.user/group — управление учётными записями
- ansible.builtin.command/shell — выполнение команд
- ansible.builtin.file — работа с файловой системой
Список всех модулей:
ansible-doc -l
Facts (Факты)
Это «датчики давления и температуры» — информация о системе, которую Ansible собирает автоматически перед выполнением задач.
Посмотреть факты о хосте:
ansible web1.example.com -m ansible.builtin.setupИли получить конкретный факт:
ansible web1.example.com -m ansible.builtin.setup -a "filter=ansible_default_ipv4"Примеры фактов:
ansible_default_ipv4.address— IP-адресansible_os_family— семейство ОС (Debian, RedHat)ansible_memory_mb.total— объём RAMansible_processor_vcpus— количество CPU
Факты можно использовать в плейбуках:
- name: Вывести информацию о системе
ansible.builtin.debug:
msg: "Сервер {{ inventory_hostname }} работает на {{ ansible_distribution }} {{ ansible_distribution_version }}"Roles (Роли)
Это «стандартизированные модули паровоза» — способ организации плейбуков для повторного использования.
Структура роли:
roles/
└── nginx/
├── defaults/
│ └── main.yml # Переменные по умолчанию
├── files/ # Статические файлы
├── handlers/
│ └── main.yml # Обработчики (restart service)
├── meta/
│ └── main.yml # Метаданные роли
├── tasks/
│ └── main.yml # Основные задачи
├── templates/ # Jinja2-шаблоны
│ └── nginx.conf.j2
└── vars/
└── main.yml # Переменные ролиИспользование роли в плейбуке:
---
- hosts: webservers
roles:
- nginx
- commonУстановка Ansible: запускаем паровой двигатель
На Control Node (Ubuntu/Debian):
# Обновить индексы пакетов
sudo apt update
# Установить Ansible
sudo apt install -y ansible
# Проверить версию
ansible --versionНа Control Node (RHEL/CentOS):
# Включить репозиторий EPEL
sudo dnf install -y epel-release
# Установить Ansible
sudo dnf install -y ansible
# Или через pip (более свежая версия)
pip3 install ansibleНастройка SSH-доступа
Ansible требует беспарольного SSH-доступа к управляемым узлам:
# Сгенерировать SSH-ключ (если ещё нет)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/ansible_rsa
# Скопировать ключ на управляемый узел
ssh-copy-id -i ~/.ssh/ansible_rsa.pub admin@web1.example.com
# Проверить доступ
ssh -i ~/.ssh/ansible_rsa admin@web1.example.comНастроить использование ключа в Ansible через ansible.cfg или inventory:
[all:vars]
ansible_ssh_private_key_file=~/.ssh/ansible_rsa
ansible_user=admin
Первый запуск: Ad-Hoc команды
Прежде чем писать плейбуки, попробуйте Ad-Hoc команды — разовые задачи, выполняемые напрямую из командной строки.
Проверка доступности хостов:
ansible all -m ansible.builtin.pingПолучение информации о системе:
ansible web1.example.com -m ansible.builtin.setup -a "filter=ansible_*_mb"Выполнение команды:
ansible all -m ansible.builtin.command -a "uptime"Установка пакета:
ansible webservers -m ansible.builtin.apt -a "name=nginx state=present" --becomeПерезапуск сервиса:
ansible webservers -m ansible.builtin.service -a "name=nginx state=restarted" --becomeКопирование файла:
ansible all -m ansible.builtin.copy -a "src=/local/file.txt dest=/remote/file.txt mode=0644" --becomeФлаги:
-m— модуль-a— аргументы модуля--become— выполнить с правами root (sudo)-i inventory.ini— использовать конкретный инвентарь
Запуск плейбука: от теории к практике
Создайте файл test_playbook.yml:
---
- name: Тестовый плейбук
hosts: all
gather_facts: yes
tasks:
- name: Вывести приветствие
ansible.builtin.debug:
msg: "Привет от {{ ansible_hostname }}!"
- name: Проверить свободное место
ansible.builtin.command: df -h /
register: disk_usage
changed_when: false
- name: Показать результат
ansible.builtin.debug:
var: disk_usage.stdout_linesЗапустите:
ansible-playbook -i inventory.ini test_playbook.ymlС флагами для отладки:
# Подробный вывод
ansible-playbook -i inventory.ini test_playbook.yml -v
# Очень подробный вывод
ansible-playbook -i inventory.ini test_playbook.yml -vvv
# Проверка синтаксиса
ansible-playbook -i inventory.ini test_playbook.yml --syntax-check
# Dry-run (проверка без изменений)
ansible-playbook -i inventory.ini test_playbook.yml --check
# Выполнить только определённые задачи
ansible-playbook -i inventory.ini test_playbook.yml --tags "configuration"
Конфигурация: ansible.cfg
Файл ansible.cfg настраивает поведение Ansible. Приоритет файлов (от высшего к низшему):
- Переменная окружения
ANSIBLE_CONFIG ./ansible.cfgв текущей директории~/.ansible.cfgв домашней директории/etc/ansible/ansible.cfgглобальный
Пример конфигурации:
[defaults]
# Путь к инвентарю
inventory = ./inventory.ini
# Отключить проверку хостов (для разработки!)
host_key_checking = False
# Таймаут SSH
timeout = 30
# Количество параллельных хостов
forks = 10
# Логирование
log_path = /var/log/ansible.log
# Формат вывода
stdout_callback = yaml
# Использовать fact caching
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
[ssh_connection]
# Ускорить SSH
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%rBest Practices: правила эксплуатации паровоза
Используйте версии модулей
# Хорошо
ansible.builtin.apt:
name: nginx
state: present
# Плохо (неявный namespace)
apt:
name: nginx
state: presentВсегда указывайте state
# Хорошо
ansible.builtin.package:
name: nginx
state: latest
# Плохо (неясно, что произойдёт)
ansible.builtin.package:
name: nginxИспользуйте handlers для перезапуска сервисов
tasks:
- name: Обновить конфигурацию
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
handlers:
- name: restart nginx
ansible.builtin.service:
name: nginx
state: restartedПрименяйте теги для гибкости
tasks:
- name: Установить пакеты
ansible.builtin.apt:
name: "{{ packages }}"
tags:
- install
- packages
- name: Настроить сервис
ansible.builtin.template:
src: config.j2
dest: /etc/service.conf
tags:
- configureЗапуск с тегами:
ansible-playbook site.yml --tags "install"
ansible-playbook site.yml --skip-tags "configure"Храните секреты в Ansible Vault
# Создать зашифрованный файл
ansible-vault create secrets.yml
# Зашифровать существующий
ansible-vault encrypt secrets.yml
# Редактировать
ansible-vault edit secrets.yml
# Посмотреть
ansible-vault view secrets.yml
# Запустить плейбук с vault
ansible-playbook site.yml --ask-vault-pass
# или
ansible-playbook site.yml --vault-password-file ~/.vault_passИспользуйте when для условного выполнения
tasks:
- name: Установить nginx только на Debian
ansible.builtin.apt:
name: nginx
when: ansible_os_family == "Debian"
- name: Установить httpd только на RedHat
ansible.builtin.yum:
name: httpd
when: ansible_os_family == "RedHat"Тестируйте с –check и –diff
ansible-playbook site.yml --check --diffОтладка: когда паровоз буксует
Включите подробное логирование:
export ANSIBLE_DEBUG=1
ansible-playbook site.yml -vvvПроверьте подключение:
ansible all -m ansible.builtin.ping -vvvПосмотрите факты:
ansible hostname -m ansible.builtin.setup | lessИспользуйте ansible-lint:
# Установить
pip install ansible-lint
# Проверить плейбук
ansible-lint site.ymlПроверьте синтаксис YAML:
python -c "import yaml; yaml.safe_load(open('playbook.yml'))"Заключение
Ansible — это не просто инструмент, а целая философия управления инфраструктурой. Его архитектура проста, но мощна: один управляющий узел, SSH-соединения, модули на Python и декларативные плейбуки в YAML.
Помните: хороший сисадмин — это не тот, кто всё делает руками, а тот, кто построил паровую машину, которая делает это за него.
⚙️ Машинное отделение ROADIT благодарит за прочтение.
Больше команд, шпаргалок и обзоров — на roadit.ru и в нашем Телеграф-канале.
📋 Все команды