Ansible — инструмент автоматизации конфигураций и развёртывания: задачи
описываются YAML-плейбуками, исполняются по SSH без агентов на целевых
машинах. Сценарий статьи: инвентарь из групп webservers/dbservers,
настраиваем на них nginx.
Установка#
Из репозитория Ubuntu приходит сильно запаздывающая версия — живее брать из официального PPA:
sudo apt update
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
ansible --version
Альтернатива, дающая самые свежие релизы:
pipx install ansible(или pip в виртуальном окружении). Не смешивайте оба способа на одной машине.
Инвентарь#
Инвентарь описывает хосты и их группы. Файл inventory.ini рядом с плейбуками:
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
db2.example.com
[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_rsa
Инвентарь по умолчанию Ansible берёт из
ansible.cfgв каталоге плейбука:# ansible.cfg [defaults] inventory = ./inventory.iniиначе каждый вызов команды придётся снабжать
-i inventory.ini.
Первый плейбук#
Плейбук — YAML со списком задач (task). Файл update.yml:
---
- name: Обновление системных пакетов
hosts: all
become: yes
tasks:
- name: Обновить кэш пакетов
apt:
update_cache: yes
- name: Установить базовый набор
apt:
name:
- nginx
- git
- curl
state: present
Запуск:
ansible-playbook update.yml
Задачи Ansible идемпотентны: повторный прогон плейбука не делает лишнего — модули сравнивают текущее состояние с желаемым и меняют только расходящееся.
Модули#
Модуль — атомарное действие. Самой ходовой хватает на большинство задач:
| Модуль | Что делает |
|---|---|
apt |
пакеты в Debian/Ubuntu |
yum, dnf |
пакеты в RHEL-семействе |
copy |
файл на удалённый хост |
template |
файл из Jinja2-шаблона с подстановкой переменных |
file |
права, владельцы, каталоги |
service |
запустить/остановить/рестартовать службу |
user, group |
пользователи и группы |
Полные имена модулей — с префиксом коллекции:
ansible.builtin.copy,ansible.builtin.service. Справка по любому:ansible-doc copy, документация — docs.ansible.com.
Переменные и обработчики#
Внутри плейбука — vars; в шаблонах — подстановка через {{ … }}.
Файл nginx.conf.j2 рядом с плейбуком:
server {
listen {{ http_port }};
root {{ document_root }};
}
Файл webserver.yml:
---
- name: Настройка веб-сервера
hosts: webservers
become: yes
vars:
http_port: 80
document_root: /var/www/html
tasks:
- name: Конфигурация nginx из шаблона
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Перезапустить nginx # сработает, только если файл изменился
handlers:
- name: Перезапустить nginx
service:
name: nginx
state: restarted
notify— обработчик (handler): запускается один раз в конце прогона и только когда задача реально что-то поменяла. Прогон без изменений рестартов службы не делает.
Роли#
Роль — переиспользуемый компонент со своей структурой каталогов:
ansible-galaxy init roles/webserver
roles/webserver/
├── tasks/main.yml # задачи роли
├── handlers/main.yml
├── templates/ # nginx.conf.j2 — сюда
├── defaults/main.yml # переменные по умолчанию
└── vars/main.yml
Использование — в плейбуке вместо перечисления задач:
---
- name: Веб-серверы
hosts: webservers
become: yes
roles:
- webserver
Готовые роли сообщества — Ansible Galaxy (
ansible-galaxy installgeerlingguy.nginx), свои кладите вroles/рядом с плейбуком.
Команды работы#
# Проверка доступности хостов (модуль ping)
ansible all -m ping
# Только одна группа
ansible webservers -m ping
# Разовая команда на хостах
ansible all -a "uptime"
# Плейбук с суперпользователем на целевых машинах
ansible-playbook webserver.yml --become
# Показать список задач, ничего не выполняя
ansible-playbook webserver.yml --list-tasks
# Сухой прогон: изменения считаются, но не применяются
ansible-playbook webserver.yml --check --diff
# Подробный вывод (v, -vv, -vvv — многословнее)
ansible-playbook webserver.yml -v
# Ограничить прогон одним хостом
ansible-playbook webserver.yml --limit web1.example.com
Секреты (пароли, ключи API) держите в зашифрованных переменных:
ansible-vault encrypt_string— и в плейбуме как обычную переменную; расшифровка запрашивает пароль vault при прогоне.