Сценарии автоматизации#
Набор сценариев (playbook) в Ansible – это основной инструмент автоматизации, представляющий собой файл в формате YAML, в котором содержится описание конфигурации целевых узлов в декларативной форме. В отличие от отдельных (ad-hoc) команд, сценарии позволяют задавать последовательность операций, определять условия их выполнения, использовать переменные, роли и другие элементы логики, характерные для полноценного программного описания инфраструктуры.
Структура набора сценариев#
Набор сценариев имеет вид списка, где каждый элемент – это отдельный сценарий, содержащий задачи по управлению указанными узлами и группами узлов инвентаря.
Для запуска сценария используется утилита командной строки ansible-playbook, обеспечивающая детальный контроль над параметрами выполнения и возможностями отладки.
ansible-playbook setup.yml -i inventory.yml
где:
setup.yml– путь к файлу набора сценариев;-i inventory.yml– путь к файлу с инвентарным списком.
Подробнее об утилите см. Утилиты.
Иерархия исполняемых компонентов в наборе сценариев представлена на схеме:
---
- name: Настройка веб-серверов
hosts: webservers
become: yes
tasks:
- name: Установка Apache
ansible.builtin.apt:
name: apache2
state: present
- name: Управление пользователями
hosts: all
become: yes
tasks:
- name: Добавление нового пользователя
ansible.builtin.user:
name: deployer
state: present
- name: Настройка брандмауэра
hosts: firewalls
become: yes
tasks:
- name: Открытие порта HTTP
ansible.posix.firewalld:
port: 80/tcp
permanent: true
state: enabled
Здесь:
Названия сценариев:
Настройка веб-серверов.Управление пользователями.Настройка брандмауэра.
Названия групп узлов:
webservers;all;firewalls.
Названия задач:
Установка Apache.Добавление нового пользователя.Открытие порта HTTP.
Названия модулей:
ansible.builtin.apt;ansible.builtin.user;ansible.posix.firewalld.
Названия переменных:
name;state;port;permanent.
Инвентарный список для связывания с набором сценариев может быть задан несколькими способами. Далее приведен список вариантов в порядке убывания приоритета:
аргумент
-i(--inventory,--inventory-file) утилитыansible-playbook;переменная окружения
ANSIBLE_INVENTORY;переменная
inventoryв конфигурационном файлеansible.cfg.
Структура сценария#
Сценарий (play) – элемент первого уровня в структуре набора сценариев. Он описывает, какие действия необходимо выполнить и на каких целевых узлах.
В сценарий входят следующие компоненты:
Компонент |
Описание |
|---|---|
Задача (task) |
Использует один из модулей Ansible для выполнения отдельной операции по управлению узлами. |
Модуль (module) |
Реализует требуемую функциональность. Например, существуют модули для копирования файлов, управления пакетами и службами и так далее. Код модулей выполняется на целевых узлах, которые в большинстве случаев и являются управляемыми. |
Расширение (plugin) |
Расширяет функциональность Ansible. В отличие от модулей, код расширений всегда выполняется на управляющем узле. |
Каждый сценарий выполняется на группе узлов, определенной в инвентаре. Все задачи в сценарии выполняются последовательно, в порядке их определения. По умолчанию выполнение сценария прерывается при возникновении ошибки в любой из задач.
Сценарий может включать следующие основные параметры:
name– название;hosts– узлы, на которых выполняются задачи;tasks– задачи для выполнения;vars– значения переменных;vars_files– список путей к файлам с переменными;become– требование повысить привилегии при выполнении задач.
Пример простого сценария:
- name: Настройка веб-серверов
hosts: webservers
become: yes
vars:
apache_package: apache2
tasks:
- name: Установка Apache
ansible.builtin.apt:
name: "{{ apache_package }}"
state: present
Помимо основных параметров, в сценариях часто используются дополнительные настройки:
gather_facts– включение или отключение сбора фактов перед выполнением задач.Значение по умолчанию:
true.remote_user– название учетной записи пользователя, под которой будет производиться подключение к узлам.serial– ограничение количества узлов, обрабатываемых одновременно.strategy– стратегия выполнения задач (например,linear,free,debug).handlers– определения действий, вызываемых только при изменении состояния (например, перезапуск службы после обновления конфигурации).pre_tasksиpost_tasks– задачи, которые выполняются до и после основного блокаtasks.roles– подключение ролей, содержащих повторно используемую логику и структуру.
Структура задачи#
Задача (task) в Ansible описывает одно конкретное действие, которое должно быть выполнено на целевом узле. Это наименьшая единица логики внутри сценария, и она исполняется модулем Ansible с переданными ему параметрами.
Все задачи в сценарии выполняются последовательно, в порядке их определения. По умолчанию выполнение сценария прерывается при возникновении ошибки в любой из задач.
В задаче, как правило, указываются следующие элементы:
name– название задачи, кратко описывающее ее назначение;модуль Ansible – название используемого модуля, например,
ansible.builtin.copyилиansible.builtin.apt;параметры модуля;
дополнительные директивы (опционально), такие как
when,loop,become,registerи другие.
---
- name: Установка Apache на веб-серверах
hosts: webservers
become: yes
tasks:
- name: Установка пакета apache2 через APT
ansible.builtin.apt:
name: apache2
state: present
В этом примере:
Название сценария –
Установка Apache на веб-серверах.Название группы узлов –
webservers.Флаг повышения привилегий –
become: yes.Название задачи –
Установка пакета apache2 через APT.Название используемого модуля –
ansible.builtin.apt.Название устанавливаемого пакета –
apache2.Желаемое состояние пакета –
present(означает, что пакет должен быть установлен).
Большинство модулей Ansible следуют принципу идемпотентности: они не выполняют действия, если это не требуется.
Например, модуль ansible.builtin.file не будет создавать файл, если он уже существует и обладает нужными атрибутами.
Примечание
В то же время идемпотентность модулей является рекомендацией а не требованием.
Кроме этого, некоторые модули, например, ansible.builtin.command, в принципе не могут быть идемпотентными.
Базовые переменные#
Ansible предоставляет ряд предопределенных переменных, которые можно использовать в сценариях:
become– выполнение задачи с привилегиями суперпользователя.Пример использования
becomeУстановка и настройка NGINX. Задачи выполняются с привилегиями суперпользователя.
--- - name: Установка и запуск NGINX hosts: webservers become: yes # Выполнение задач с повышенными привилегиями tasks: - name: Установить NGINX ansible.builtin.apt: name: nginx state: present - name: Запустить NGINX ansible.builtin.service: name: nginx state: started enabled: yes
ansible_facts– факты об узле.Пример использования
ansible_factsНастройка NGINX, при которой число
worker_processesв конфигурационном файле задается на основе количества доступных ядер процессоров:--- - name: Настройка NGINX в зависимости от числа ядер CPU hosts: webservers become: yes tasks: - name: Создать конфигурационный файл ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf vars: cpu_cores: "{{ ansible_facts['processor_cores'] }}" - name: Перезапустить NGINX ansible.builtin.service: name: nginx state: restarted
inventory_hostname– название узла в инвентарном списке.Пример использования
inventory_hostnameСоздание лог-файла с названием, соответствующим конкретному серверу:
--- - name: Создание лог-файлов hosts: all tasks: - name: Создать лог-файл для каждого узла ansible.builtin.file: path: "/var/logs/{{ inventory_hostname }}.log" state: touch
playbook_dir– каталог с текущим набором сценариев.Пример использования
playbook_dirКопирование конфигурационного файла
app.conf:--- - name: Развертывание конфигурации hosts: all become: yes tasks: - name: Копировать конфиг ansible.builtin.copy: src: "{{ playbook_dir }}/files/app.conf" dest: /etc/app/app.conf mode: '0644'
Кроме того, можно определять пользовательские переменные для использования в сценариях.
Сбор данных#
Ansible может собирать информацию об управляемых узлах, называемую фактами (facts). Факты используются для динамического изменения значений переменных, адаптации сценариев к конфигурации ОС и оборудования. Они могут быть полезны для определения ОС и выбора соответствующих пакетов, получения информации о сетевых интерфейсах, проверки параметров аппаратного обеспечения перед установкой ПО и так далее.
Сбором фактов управляет переменная gather_facts.
По умолчанию ее значение равно true.
---
- name: Сбор информации о системе
hosts: all
tasks:
- name: Вывод названия семейства ОС
ansible.builtin.debug:
msg: "ОС: {{ ansible_facts['os_family'] }}"
Если сценарий не использует факты, их сбор можно отключить для ускорения выполнения, установив переменной gather_facts значение false.
---
- name: Развертывание конфигурации
hosts: all
gather_facts: false
tasks:
- name: Копирование конфигурационного файла
ansible.builtin.copy:
src: myconfig.cfg
dest: /etc/myconfig.cfg
Управление пакетами и службами#
Ansible позволяет устанавливать и удалять пакеты, а также управлять службами. Для этого используются разные модули:
В ОС Astra Linux для управления пакетами используйте модуль
ansible.builtin.apt.Для управления службами используйте модули
ansible.builtin.serviceилиansible.builtin.systemd.
---
- name: Установка и управление Apache
hosts: webservers
tasks:
- name: Установка Apache
ansible.builtin.apt:
name: apache2
state: present
- name: Запуск службы Apache с помощью модуля ansible.builtin.service
ansible.builtin.service:
name: apache2
state: started
- name: Перезапуск службы Apache с помощью модуля ansible.builtin.systemd
ansible.builtin.systemd:
name: apache2
state: restarted
- name: Остановка и отключение автозапуска Apache с помощью модуля ansible.builtin.systemd
ansible.builtin.systemd:
name: apache2
state: stopped
enabled: false
- name: Удаление пакетов Apache
ansible.builtin.apt:
name: apache2
state: absent
Управление файлами#
Ansible предоставляет ряд модулей для работы с файлами и каталогами, каждый из которых выполняет определенные задачи:
ansible.builtin.blockinfile– работа с блоками текста: добавление, изменение или удаление.ansible.builtin.copy– копирование файлов с управляющего узла на управляемые, при необходимости изменяя права доступа и владельца.ansible.builtin.fetch– копирование файлов с управляемых узлов на управляющий.ansible.builtin.file– управление файлами и каталогами: создание, удаление, изменение прав доступа и владельцев, а также установка временных меток.ansible.builtin.get_url– загрузка файлов из сети и сохранение их на целевых узлах.ansible.builtin.lineinfile– управление отдельными строками в файле: добавление, изменение или удаление.ansible.builtin.replace– замена текста в файлах с использованием регулярных выражений.ansible.builtin.stat– проверка наличия файла или каталога, а также получение сведений о его свойствах.ansible.builtin.template– обработка текстовых файлов с помощью шаблонизатора Jinja и их копирование в указанное расположение на управляемых узлах.
templates/nginx.conf.j2#server {
listen 80;
server_name {{ server_name }};
root {{ document_root }};
}
---
- name: Развертывание конфигурационного файла из шаблона
hosts: all
vars:
server_name: example.com
document_root: /var/www/html
tasks:
- name: Создать конфигурационный файл из шаблона
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
Переменные#
Переменные позволяют задавать динамические значения в сценариях. Они могут хранить строки, числа, списки и сложные структуры данных.
Значения переменным могут быть присвоены следующими способами:
В сценарии внутри секции
vars.В отдельных файлах формата YAML. Затем эти файлы подключаются к задачам в блоке
vars_files.В файлах формата YAML из каталогов
group_vars/иhost_vars/, размещенных в одном каталоге с набором сценариев.Через аргумент командной строки
-e.Используя значения фактов (
ansible_facts).
При определении действующего значения переменной Ansible использует следующий порядок: более специфичное (более узкое) определение (например, для узла) обладает более высоким приоритетом над общим определением (например, для группы узлов).
Список источников значений переменных в порядке возрастания приоритета:
Значения, переданные через командную строку (например,
-u my_user). Эти параметры не являются переменными и имеют самый низкий приоритет.Значения по умолчанию, заданные в определении роли (в каталоге роли).
Групповые переменные из файла со статическим описанием инвентаря или заданные с помощью сценария динамического определения инвентаря.
Групповые переменные инвентаря, заданные в файле
group_vars/all[.yml]. Каталогgroup_vars/находится в одном каталоге с файлом инвентаря.Групповые переменные набора сценариев, заданные в файле
group_vars/all[.yml].Групповые переменные инвентаря, заданные для групп индивидуально в файлах
group_vars/<group_name>[.yml].Групповые переменные набора сценариев, заданные для групп индивидуально в файлах
group_vars/<group_name>[.yml].Переменные узла из файла со статическим описанием инвентаря или заданные с помощью сценария динамического определения инвентаря.
Переменные узла, заданные для описания инвентаря в файле
host_vars/<host_name>[.yml].Переменные узла, заданные для сценариев в файле
host_vars/<host_name>[.yml].Факты узла, включая
ansible_factsи кешированные переменные, установленные черезset_facts.Переменные, объявленные в сценарии в секции
vars.Переменные, запрашиваемые у пользователя во время выполнения сценария через
vars_prompt.Переменные, загружаемые из файлов, указанных в секции
vars_files.Переменные роли, заданные в файлах из ее каталога
vars/.Переменные, объявленные внутри блока и применимые только к задачам в этом блоке (block vars).
Переменные, объявленные внутри задачи и доступные только в рамках ее выполнения (task vars).
Переменные, загруженные во время выполнения сценария с помощью
include_vars.Переменные, установленные во время выполнения сценария через
set_factsили сохраненные как зарегистрированные переменные.Параметры, переданные в роли и
include_roleпри их вызове.Параметры, переданные при использовании
include_*для подключения сценариев или файлов.Дополнительные переменные (extra vars), переданные в аргументе командной строки
-e.
Пример сценария с использованием переменной и несколькими уровнями приоритетов
vars_file.yml#package_name: apache2 # Переменная в файле переменных
install_package.yml#---
- name: Установка пакета с разными источниками переменных
hosts: localhost
vars_files:
- vars_file.yml # Подключение файла переменных
vars:
package_name: nginx # Переменная на уровне сценария
tasks:
- name: Установить {{ package_name }}
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
В этом примере переменная package_name будет иметь значение apache2, потому что переменные, загруженные из файлов, имеют более высокий приоритет, чем переменные, заданные в сценарии.
Условные выражения#
Условные выражения позволяют выполнять задачи только при соблюдении определенного условия.
В Ansible для этого используется параметр when, который проверяет условие перед выполнением задачи.
Если условие выполняется, выполняется и задача. В противном случае она пропускается.
---
- name: Установка Apache только для Astra Linux
hosts: webservers
tasks:
- name: Установить apache2, если ОС - Astra Linux
ansible.builtin.apt:
name: apache2
state: present
when: ansible_facts['ansible_distribution'] == "Astra Linux"
В данном примере задача по установке пакета apache2 будет выполняться только на тех узлах, на которых название дистрибутива равно строке Astra Linux.
Это условие проверяется с помощью факта ansible_distribution.
Он содержит название дистрибутива ОС, под управлением которого работает управляемый узел.
Циклы#
Ansible поддерживает циклы для выполнения одной задачи несколько раз с разными значениями параметров.
Для задания цикла используется директива loop, в которой указывается список значений.
Каждое значение по умолчанию передается в задачу в виде переменной item.
Циклы можно сочетать с дополнительными директивами управления, например:
loop_control– настройка цикла. Например, изменение названия переменной цикла (loop_var), управление тем, как элементы отображаются в выводе (label) и так далее.until– условие прерывания цикла.retries– количество попыток повторного выполнения при использованииuntil.delay– интервал между попытками (в секундах).pause– пауза между итерациями.
Пример создания нескольких пользователей с использованием цикла
---
- name: Создание нескольких пользователей
hosts: all
become: yes
tasks:
- name: Добавление пользователей
ansible.builtin.user:
name: "{{ item }}"
state: present
loop:
- user1
- user2
- user3
В этом примере кода модуль ansible.builtin.user используется для создания учетных записей пользователей user1, user2 и user3.
Список названий учетных записей хранится в блоке loop.
Для получения действующего значения названия учетной записи используется переменная item, которая последовательно принимает указанные значения.
Пример цикла с контролем выполнения и проверкой условия
Первая задача этого сценария проверяет статус службы по указанным URI. На проверку дается 5 попыток с интервалом 10 секунд.
---
- name: Проверка запуска службы
hosts: app_servers
become: yes
tasks:
- name: Проверка доступности веб-приложения
ansible.builtin.uri:
url: "{{ endpoint }}"
status_code: 200
register: result
until: result.status == 200
retries: 5
delay: 10
loop:
- "http://localhost:8080/health"
- "http://localhost:9090/status"
loop_control:
loop_var: endpoint
label: "{{ endpoint }}"
vars:
ansible.builtin.uri.url: "{{ endpoint }}"
Здесь:
loop– перебор списка URL-адресов, которые нужно проверить;loop_control.loop_var– использование названия переменнойendpointвместоitem;loop_control.label– управление отображением в выводе (например, название проверяемого URL);register– сохранение результата выполнения задачи в переменнуюresult;until– указание условия: задача должна вернуть HTTP-статус 200;retries– количество попыток получения HTTP-статуса 200;delay– интервал между попытками в секундах.