Перейти к основному содержимому

7.04. Справочник по Ansible

Разработчику Архитектору Инженеру

Справочник по Ansible

Ansible — это система автоматизации конфигурации, развёртывания и управления инфраструктурой. Она использует декларативный подход для описания состояния систем и применяет его без необходимости установки агентов на управляемые узлы. Ansible работает через SSH и поддерживает широкий спектр операционных систем, облачных платформ и сетевых устройств.


Архитектура Ansible

Ansible состоит из следующих ключевых компонентов:

  • Контрольная нода — машина, с которой запускаются команды и плейбуки. На ней установлен Ansible.
  • Управляемые узлы — хосты, к которым применяется автоматизация. Они не требуют установки специального ПО, кроме интерпретатора Python (или PowerShell в случае Windows).
  • Инвентарь — файл или каталог, определяющий список управляемых узлов и их группировку.
  • Модули — исполняемые единицы кода, которые выполняют конкретные задачи: установка пакетов, управление службами, работа с файлами и т.д.
  • Плейбуки — YAML-файлы, описывающие последовательность задач, применяемых к определённым хостам.
  • Роли — структурированные наборы задач, переменных, шаблонов и обработчиков, предназначенные для повторного использования.
  • Факты — данные, собранные с управляемых узлов (например, версия ОС, объём памяти, IP-адреса).
  • Vault — механизм шифрования чувствительных данных, таких как пароли и ключи.
  • AWX / Red Hat Ansible Automation Platform — веб-интерфейс и API для управления автоматизацией на основе Ansible.

Инвентарь (Inventory)

Инвентарь может быть представлен в виде INI- или YAML-файла. Он определяет хосты, группы, переменные и параметры подключения.

Пример INI-инвентаря

[webservers]
web1.example.com
web2.example.com

[databases]
db1.example.com ansible_user=postgres

[production:children]
webservers
databases

[webservers:vars]
ansible_ssh_private_key_file=~/.ssh/prod_key

Пример YAML-инвентаря

all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
vars:
http_port: 80
databases:
hosts:
db1.example.com:
vars:
ansible_user: postgres

Специальные переменные инвентаря

  • ansible_host — реальный IP или доменное имя хоста.
  • ansible_port — порт SSH.
  • ansible_user — имя пользователя для подключения.
  • ansible_password — пароль (не рекомендуется использовать напрямую).
  • ansible_ssh_private_key_file — путь к приватному SSH-ключу.
  • ansible_connection — тип подключения (ssh, local, winrm, docker и др.).
  • ansible_python_interpreter — путь к интерпретатору Python на удалённой машине.

Плейбуки (Playbooks)

Плейбук — это основной способ описания автоматизации в Ansible. Он состоит из одного или нескольких play, каждый из которых применяет набор задач к определённой группе хостов.

Структура play

- name: Установка и настройка веб-сервера
hosts: webservers
become: yes
vars:
http_port: 80
tasks:
- name: Установить Apache
apt:
name: apache2
state: present
- name: Запустить службу Apache
service:
name: apache2
state: started
enabled: yes

Ключевые директивы play

  • name — описание play.
  • hosts — целевые хосты или группы.
  • become — выполнение задач от имени другого пользователя (обычно root).
  • become_user — указание пользователя для повышения привилегий.
  • vars — локальные переменные для play.
  • vars_files — загрузка переменных из внешних файлов.
  • tasks — список задач.
  • handlers — обработчики, вызываемые по событию.
  • roles — подключение ролей.
  • pre_tasks / post_tasks — задачи до и после применения ролей.
  • environment — установка переменных окружения для всех задач в play.

Задачи (Tasks)

Каждая задача вызывает модуль с определёнными параметрами.

Примеры задач

- name: Создать директорию
file:
path: /opt/app
state: directory
mode: '0755'

- name: Скопировать конфигурационный файл
copy:
src: files/app.conf
dest: /etc/app.conf
owner: root
group: root
mode: '0644'

- name: Выполнить команду
command: /usr/bin/make_database.sh
args:
chdir: /opt/app
creates: /var/db/database.sqlite

Общие параметры задач

  • name — описание задачи.
  • when — условие выполнения задачи.
  • loop — итерация по списку значений.
  • register — сохранение результата задачи в переменную.
  • notify — вызов обработчика.
  • ignore_errors — продолжение выполнения при ошибке.
  • delegate_to — выполнение задачи на другом хосте.
  • run_once — выполнение задачи только один раз в группе.

Обработчики (Handlers)

Обработчики — это специальные задачи, которые запускаются только при получении уведомления из других задач.

tasks:
- name: Обновить конфигурацию Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Перезапустить Nginx

handlers:
- name: Перезапустить Nginx
service:
name: nginx
state: reloaded

Обработчики выполняются в конце play, даже если уведомление пришло несколько раз.


Переменные (Variables)

Ansible поддерживает множество источников переменных:

  • Внутри плейбука (vars, vars_files)
  • В ролях (roles/rolename/vars/main.yml)
  • В инвентаре (group_vars/, host_vars/)
  • Через командную строку (-e "var=value")
  • Факты, собранные с хостов (setup модуль)
  • Регистрация результатов задач (register)

Приоритет переменных (от низкого к высокому)

  1. Факты (gathered facts)
  2. role defaults
  3. inventory vars
  4. inventory group_vars
  5. inventory host_vars
  6. playbook vars
  7. playbook vars_files
  8. role vars
  9. block vars
  10. task vars
  11. extra vars (-e)

Роли (Roles)

Роли позволяют организовать код в повторно используемые компоненты. Стандартная структура роли:

roles/
common/
tasks/
handlers/
templates/
files/
vars/
defaults/
meta/
  • tasks/main.yml — основные задачи роли.
  • handlers/main.yml — обработчики.
  • templates/ — шаблоны Jinja2.
  • files/ — статические файлы для копирования.
  • vars/main.yml — переменные с высоким приоритетом.
  • defaults/main.yml — переменные по умолчанию.
  • meta/main.yml — зависимости и метаданные.

Использование роли в плейбуке

- name: Применить роль базовой настройки
hosts: all
roles:
- common

Шаблоны (Templates)

Шаблоны используют движок Jinja2 и позволяют генерировать конфигурационные файлы с подстановкой переменных.

Пример шаблона nginx.conf.j2

server {
listen {{ nginx_port }};
server_name {{ nginx_server_name }};

location / {
root {{ nginx_root }};
index index.html;
}
}

Использование в задаче

- name: Развернуть шаблон Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default

Модули (Modules)

Ansible поставляется с сотнями встроенных модулей. Ниже перечислены наиболее часто используемые категории и примеры.

Управление пакетами

  • apt — для Debian/Ubuntu
  • yum / dnf — для RHEL/CentOS/Fedora
  • pacman — для Arch Linux
  • package — универсальный модуль

Управление службами

  • service — управление systemd/sysvinit службами
  • systemd — расширенное управление через systemd

Работа с файлами

  • file — создание, изменение прав, удаление
  • copy — копирование локальных файлов
  • template — развертывание шаблонов
  • lineinfile — изменение отдельных строк
  • replace — замена текста по регулярному выражению

Выполнение команд

  • command — выполнение команды без оболочки
  • shell — выполнение с оболочкой (поддержка пайпов, переменных)
  • script — запуск локального скрипта на удалённом хосте

Работа с пользователями и группами

  • user — управление учётными записями
  • group — управление группами

Сетевые и облачные модули

  • uri — HTTP-запросы
  • get_url — загрузка файлов по URL
  • amazon.aws.ec2 — управление EC2-инстансами
  • azure_rm_virtualmachine — управление Azure VM
  • vmware_guest — управление VMware

Условия и циклы

Условия (when)

- name: Установить пакет только на Ubuntu
apt:
name: nginx
state: present
when: ansible_distribution == "Ubuntu"

Циклы (loop)

- name: Создать пользователей
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie

Поддерживаемые конструкции: loop, with_items, with_dict, with_fileglob, with_sequence.


Ansible Vault

Vault позволяет шифровать файлы с чувствительными данными.

Основные команды

  • ansible-vault create secrets.yml — создать зашифрованный файл
  • ansible-vault edit secrets.yml — редактировать
  • ansible-vault view secrets.yml — просмотреть содержимое
  • ansible-vault encrypt existing.yml — зашифровать существующий файл
  • ansible-vault decrypt existing.yml — расшифровать

Использование в плейбуке

ansible-playbook site.yml --ask-vault-pass

Или с файлом пароля:

ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt

AWX и Red Hat Ansible Automation Platform

AWX — это open-source веб-интерфейс для управления Ansible. Red Hat Ansible Automation Platform — коммерческая версия с поддержкой, RBAC, workflow и аналитикой.

Основные возможности:

  • Централизованное управление инвентарём
  • Запуск плейбуков через веб-интерфейс
  • Планирование заданий
  • Управление учетными данными
  • Визуальные workflow
  • REST API

Полезные команды CLI

  • ansible all -m ping — проверка подключения ко всем хостам
  • ansible-inventory --list — вывод инвентаря в JSON
  • ansible-doc <module> — справка по модулю
  • ansible-playbook playbook.yml — запуск плейбука
  • ansible-galaxy install geerlingguy.nginx — установка роли из Galaxy
  • ansible-config dump --only-changed — показать изменённые настройки

Конфигурационный файл ansible.cfg

Расположение: /etc/ansible/ansible.cfg, ~/.ansible.cfg, ./ansible.cfg.

Пример настроек

[defaults]
inventory = ./inventory
remote_user = ubuntu
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml
callback_whitelist = profile_tasks

[privilege_escalation]
become = True
become_method = sudo
become_user = root

Часто используемые параметры

  • inventory — путь к файлу инвентаря
  • remote_user — пользователь по умолчанию
  • host_key_checking — отключение проверки SSH-ключа
  • roles_path — дополнительные пути для ролей
  • collections_paths — пути для коллекций
  • timeout — таймаут подключения
  • forks — количество параллельных процессов

Коллекции (Collections)

Коллекции — это современный способ распространения и организации контента Ansible: модулей, плейбуков, ролей, инвентарных плагинов и документации. Они заменили отдельные репозитории Galaxy для ролей и позволяют группировать связанные компоненты.

Структура коллекции

my_namespace.my_collection/
├── galaxy.yml # Метаданные коллекции
├── README.md
├── docs/
├── plugins/
│ ├── modules/
│ ├── inventory/
│ ├── filter/
│ └── lookup/
├── roles/
└── playbooks/

Установка коллекций

# Из Ansible Galaxy
ansible-galaxy collection install community.general

# Из локального архива
ansible-galaxy collection install ./my_collection-1.0.0.tar.gz

# Из Git-репозитория
ansible-galaxy collection install git+https://github.com/namespace/collection.git

Использование модулей из коллекции

- name: Создать пользователя через модуль из коллекции
community.general.user:
name: alice
state: present

Если коллекция указана в collections: на уровне play, можно использовать модули без префикса:

- name: Play с указанием коллекции
hosts: all
collections:
- community.general
tasks:
- user:
name: bob
state: present

Динамический инвентарь

Динамический инвентарь позволяет получать список хостов из внешних источников: облака (AWS, Azure, GCP), системы оркестрации (Kubernetes), CMDB или API.

Пример: AWS EC2 Dynamic Inventory

Файл aws_ec2.yaml:

plugin: aws_ec2
regions:
- us-east-1
- eu-west-1
keyed_groups:
- key: tags.Environment
prefix: env
- key: instance_type
prefix: type

Запуск:

ansible-inventory -i aws_ec2.yaml --list
ansible-playbook -i aws_ec2.yaml site.yml

Поддерживаемые источники:

  • amazon.aws.aws_ec2
  • azure.azcollection.azure_rm
  • google.cloud.gcp_compute
  • kubernetes.core.k8s
  • vmware.vmware_rest.vm_inventory

Отладка и тестирование

Вывод отладочной информации

- name: Показать значение переменной
debug:
var: my_variable

- name: Показать сообщение
debug:
msg: "Текущий порт: {{ http_port }}"

Режим подробного вывода

ansible-playbook playbook.yml -v      # базовый уровень
ansible-playbook playbook.yml -vvv # подробный вывод задач
ansible-playbook playbook.yml -vvvvv # включая SSH-команды

Проверка синтаксиса

ansible-playbook playbook.yml --syntax-check

Dry-run (проверка без изменений)

ansible-playbook playbook.yml --check

Тестирование ролей с Molecule

Molecule — фреймворк для тестирования ролей Ansible.

Установка:

pip install molecule[docker]

Создание шаблона:

molecule init role my_role

Структура:

my_role/
├── molecule/
│ └── default/
│ ├── converge.yml # плейбук применения роли
│ ├── verify.yml # проверка состояния
│ └── molecule.yml # конфигурация драйвера (Docker, Vagrant)

Запуск:

cd my_role
molecule test

Best Practices

Организация проекта

production.yml          # точка входа для production
staging.yml # для staging-среды
group_vars/
all.yml # глобальные переменные
webservers.yml
host_vars/
web1.example.com.yml
roles/
nginx/
postgresql/
inventory/
production/
hosts.ini
group_vars/
collections/
requirements.yml

Использование requirements.yml

collections:
- name: community.general
- name: amazon.aws
version: ">=5.0.0"
roles:
- src: geerlingguy.nginx
version: "3.0.0"

Установка зависимостей:

ansible-galaxy install -r requirements.yml
ansible-galaxy collection install -r requirements.yml

Безопасность

  • Никогда не храните пароли в открытом виде.
  • Используйте ansible-vault для всех чувствительных данных.
  • Ограничьте права пользователей на управляемых узлах.
  • Используйте become: yes только при необходимости.
  • Регулярно обновляйте Ansible и коллекции.

Читаемость

  • Все задачи должны иметь name.
  • Используйте осмысленные имена переменных.
  • Разбивайте сложные плейбуки на роли.
  • Документируйте неочевидные решения в комментариях.

Распространённые параметры модулей

Ниже приведены универсальные параметры, поддерживаемые большинством модулей:

ПараметрОписание
stateЖелаемое состояние (present, absent, started, stopped, latest)
nameИмя пакета, службы, пользователя и т.д.
pathПуть к файлу или директории
src / destИсходный и целевой путь для копирования
owner / groupВладелец и группа файла
modeПрава доступа (в виде строки '0644')
backupСоздавать резервную копию перед изменением (yes/no)
createsНе выполнять команду, если файл уже существует
removesВыполнять команду только если файл существует

Факты (Facts)

Ansible автоматически собирает информацию о хостах через модуль setup.

Просмотр фактов:

ansible hostname -m setup

Отключение сбора фактов (для ускорения):

- hosts: all
gather_facts: no

Ручной вызов:

- setup:
filter: ansible_*_ipv4

Примеры полезных фактов:

  • ansible_distribution — имя ОС (Ubuntu, CentOS)
  • ansible_architecture — архитектура (x86_64)
  • ansible_memtotal_mb — объём RAM
  • ansible_default_ipv4.address — основной IP-адрес

Обработка ошибок

Игнорирование ошибок

- name: Выполнить команду, даже если она завершится с ошибкой
command: /bin/false
ignore_errors: yes

Блоки и обработка исключений

- block:
- name: Задача, которая может завершиться ошибкой
command: risky_command
rescue:
- name: Реакция на ошибку
debug:
msg: "Произошла ошибка"
always:
- name: Выполняется всегда
debug:
msg: "Завершение блока"

Производительность

  • Увеличение forks в ansible.cfg ускоряет выполнение на множестве хостов.
  • Использование pipelining = True снижает количество SSH-соединений.
  • Отключение fact gathering при ненужности.
  • Кэширование фактов:
[defaults]
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_cache
fact_caching_timeout = 3600

Расширение возможностей

Фильтры (Filters)

Jinja2-фильтры для преобразования данных:

- debug:
msg: "{{ 'hello world' | upper }}" # HELLO WORLD

- debug:
msg: "{{ [1,2,3] | join(',') }}" # 1,2,3

- debug:
msg: "{{ some_dict | to_nice_json }}"

Часто используемые фильтры:

  • default(value) — значение по умолчанию
  • bool — преобразование строки в булево
  • basename / dirname — работа с путями
  • ipaddr — операции с IP-адресами
  • regex_replace — замена по регулярному выражению

Lookup-плагины

Получение данных из внешних источников:

- name: Прочитать содержимое файла
debug:
msg: "{{ lookup('file', '/etc/motd') }}"

- name: Получить переменную из Vault
debug:
msg: "{{ lookup('env', 'HOME') }}"

- name: Запрос к DNS
debug:
msg: "{{ lookup('dig', 'example.com') }}"

Примеры полных плейбуков

Базовый плейбук для настройки веб-сервера

---
- name: Настройка Nginx на Ubuntu
hosts: webservers
become: yes
vars:
nginx_port: 80
app_root: /var/www/myapp
tasks:
- name: Установить необходимые пакеты
apt:
name:
- nginx
- curl
state: present
update_cache: yes

- name: Создать директорию приложения
file:
path: "{{ app_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'

- name: Развернуть HTML-файл
copy:
content: "<h1>Привет из Ansible!</h1>"
dest: "{{ app_root }}/index.html"
owner: www-data
group: www-data
mode: '0644'

- name: Скопировать конфигурацию Nginx
template:
src: nginx-site.conf.j2
dest: /etc/nginx/sites-available/myapp
notify: Перезапустить Nginx

- name: Активировать сайт
file:
src: /etc/nginx/sites-available/myapp
dest: /etc/nginx/sites-enabled/myapp
state: link

handlers:
- name: Перезапустить Nginx
service:
name: nginx
state: reloaded

Шаблон nginx-site.conf.j2:

server {
listen {{ nginx_port }};
root {{ app_root }};
index index.html;
server_name _;
}

Плейбук с использованием ролей и коллекций

---
- name: Развёртывание базы данных PostgreSQL
hosts: databases
become: yes
collections:
- community.postgresql
roles:
- geerlingguy.postgresql
vars:
postgresql_databases:
- name: myapp_db
postgresql_users:
- name: myapp_user
password: "{{ vault_db_password }}"
priv: "ALL"

Переменная vault_db_password хранится в зашифрованном файле через ansible-vault.


Работа с Windows

Ansible поддерживает управление Windows-хостами через протокол WinRM.

Требования

  • На Windows должен быть включён WinRM.
  • PowerShell версии 3.0 или выше.
  • Учётная запись с правами администратора.

Пример инвентаря для Windows

[windows]
win1 ansible_host=192.168.1.10

[windows:vars]
ansible_user=Administrator
ansible_password=SecurePass123
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore

Пример задачи

- name: Создать пользователя на Windows
win_user:
name: alice
password: "{{ user_password }}"
state: present
groups:
- Users

Поддерживаемые модули:

  • win_package — установка MSI/EXE
  • win_service — управление службами
  • win_copy — копирование файлов
  • win_reboot — перезагрузка
  • win_updates — установка обновлений

Работа с сетевыми устройствами

Ansible позволяет управлять маршрутизаторами, коммутаторами и межсетевыми экранами от Cisco, Juniper, Arista и других.

Особенности

  • Подключение не через SSH к ОС, а через CLI или API устройства.
  • Используется режим network_cli или httpapi.
  • Не требуется Python на устройстве.

Пример инвентаря

[switches]
core-sw1 ansible_host=10.0.0.1

[switches:vars]
ansible_network_os=ios
ansible_connection=network_cli
ansible_user=admin
ansible_password=secret

Пример задачи

- name: Настроить VLAN на Cisco IOS
cisco.ios.ios_vlans:
config:
- vlan_id: 100
name: WebServers
state: merged

Поддерживаемые платформы:

  • cisco.ios
  • arista.eos
  • junipernetworks.junos
  • vyos.vyos
  • paloaltonetworks.panos

Создание кастомных модулей

Пользовательские модули пишутся на Python и размещаются в каталоге library/ проекта.

Пример простого модуля hello.py

#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule

def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=True)
)
)
name = module.params['name']
greeting = f"Hello, {name}!"
module.exit_json(changed=False, msg=greeting)

if __name__ == '__main__':
main()

Использование в плейбуке

- name: Использовать кастомный модуль
hello:
name: Alice
register: result

- debug:
var: result.msg

Модуль должен быть исполняемым и возвращать JSON через exit_json() или fail_json().


Расширенные возможности

Факты на лету

- name: Добавить факт
set_fact:
app_version: "2.1.0"

- debug:
msg: "Версия приложения: {{ app_version }}"

Регистрация и условная логика

- name: Проверить существование файла
stat:
path: /opt/app/config.ini
register: config_stat

- name: Скопировать конфиг, если отсутствует
copy:
src: default.conf
dest: /opt/app/config.ini
when: not config_stat.stat.exists

Параллельное выполнение с делегированием

- name: Обновить DNS-запись после развёртывания
delegate_to: dns-server.internal
run_once: yes
uri:
url: "https://dns-api/update?host={{ inventory_hostname }}&ip={{ ansible_default_ipv4.address }}"
method: POST
headers:
Authorization: "Bearer {{ vault_dns_token }}"

Профилирование и оптимизация

Включение профилирования задач

В ansible.cfg:

[defaults]
callback_whitelist = profile_tasks

Вывод будет содержать время выполнения каждой задачи.

Кэширование фактов

[defaults]
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600

Позволяет избежать повторного сбора фактов при частых запусках.


Безопасность и лучшие практики

  • Все чувствительные данные шифруются через ansible-vault.
  • Используйте --diff для просмотра изменений в файлах.
  • Применяйте --check перед реальным запуском.
  • Избегайте shell без крайней необходимости — предпочтителен command.
  • Не храните пароли в group_vars/all; используйте host_vars или Vault.
  • Ограничьте права пользователей на целевых хостах.
  • Регулярно обновляйте Ansible и коллекции через requirements.yml.

Интеграция с CI/CD

Ansible легко встраивается в GitLab CI, GitHub Actions, Jenkins.

Пример шага в GitHub Actions

- name: Запустить плейбук
run: |
ansible-playbook -i inventory/prod site.yml --vault-password-file .vault_pass
env:
ANSIBLE_HOST_KEY_CHECKING: "False"

Файл .vault_pass хранится как секрет репозитория.


Полезные ресурсы