Оглавление:
Карта сайта:
Оглавление:
Карта сайта:
Это старая версия документа!
Рассмотрим 2 варианта:
а) Выполнять задачу после rescue, если основной сценарий выполнился с ошибкой:
- name: Основной сценарий
block:
...
rescue:
- name: Выполнить, если произошла ошибка
debug:
msg: 'Show error'
б) Выполнять задачу после always независимо от результата выполнения основного сценария:
- name: Основной сценарий
block:
...
always:
- name: Выполнить в любом случае
command: rm -f /tmp/test
в) И то и другое:
- name: Основной сценарий
block:
...
rescue:
- name: Выполнить, если произошла ошибка
debug:
msg: 'Show error'
always:
- name: Выполнить в любом случае
command: rm -f /tmp/test
* в данном примере мы отобразим текст Show error только при наличии ошибки, а также выполним команду rm -f /tmp/test независимо от исхода работы сценария.
Чтобы при ошибке выполнения на одном из серверов прекратилось выполнение на всех, нужно добавить any_errors_fatal: true перед блоком задач
- name: test-playbook hosts: servers any_errors_fatal: true tasks: - name: Создание файла file: dest: /home/file.txt state: touch owner: root group: root mode: 0644
market.yandex.ru РЕКЛАМА Главная DevOps Ansible Синтаксис playbook'ов Ansible
2022-06-15
1742 Синтаксис playbook'ов Ansible Описание Playbook — это сценарий, описывающий действия, которые нужно выполнить на управляемых хостах.
Особенности: Пишется на YAML; Действия выполняются последовательно в том порядке, в котором написаны; Идемпотентность - проверяется, достигнуто ли желаемое конечное состояние, и если это состояние достигнуто работа завершается без выполнения каких-либо действий, так что повторение задачи не изменяет конечное состояние; Начинается с трех тире (—), обозначающих начало документа; Комментарии обозначаются решеткой #; Отступ - 2 пробела. Запуск сценария осуществляется командой ansible-playbook main.yaml Структура файла playbook
— #Начинается всегда с трех тире - name: test-playbook #Имя playbook (любое)
hosts: servers #Группа хостов, на которых будет происходить выполнение (своя группа, all, ungroupt, localhost) become: true #Запускать все задачи с правами суперпользователя (true или false, по умолчанию - false) gather_facts: true #Осуществлять или нет сбор фактов (данных об управляемых хостах) (true или false, по умолчанию - true) vars: #Список переменных для этого сценария owner: root custom_var: 42 vars_files: #Файлы с переменными - vars.yaml
tasks: #Список задач
- name: block examples tasks #Объединенный блок нескольких задач, для которого можно задать условие, теги и.т.д.
block:
- name: Установка apache в centos
yum:
name: httpd
update_cache: true
state: present
service:
name: httpd
state: started
enabled: true
tags: tag1, tag2 #Теги
when: ansible_os_family == "RedHat" #Условие выполнения
file: #Модуль
dest: /var/www/html/index.html #Аргументы
state: touch
owner: "{{ owner }}" #Использование переменной, всегда выделяется кавычками
group: "{{ owner }}"
mode: 0644
tags: tag1, tag2
notify: Restart httpd #Вызывается handlers только если произошли изменения
handlers:
- name: Restart httpd
service:
name: httpd
state: restarted
Основными группами простого сценария являются: hosts — управляемые узлы или группы узлов, к которым нужно применить изменения, можно указать список; tasks — задачи описывающие состояние, в которое необходимо привести управляемый узел, могут быть выделены в роли; roles — объединение содержимого, такого как файлы, шаблоны, задачи и т.д. в одну роль для ее последующего вызова gather_facts — собирать или нет информацию об узлах перед выполнением задач, по умолчанию — да; vars — переменные, которые будут использованы при выполнении сценария; block — объединение нескольких задач в блок для которого можно указать условие и теги vars_files — список файлов с переменными pre_tasks — список задач, выполняемых перед другими задачами post_tasks — список задач, выполняемых после других задач handlers — список задач, выполняемых после вызова из другой задачи Задачи в блоке handlers называются обработчиками и выполняются в тех случаях, если в результате выполнения вызывающей их задачи произошли изменения. Обработчики выполняются только после завершения задач и только один раз. Обработчики выполняются в порядке следования в разделе handlers. В основном обработчики используются для перезапуска служб после изменения конфигурационных файлов.
Основными параметрами простого сценария являются: connection — можно указать метод соединения с узлами: pure ssh, paramiko, fireball, chroot, jail, local, accelerate (применимо также для выполнения отдельного модуля); sudo — после установления соединения выполнять задачу с привилегиями другого пользователя, по умолчанию другой пользователь — root; sudo_user — в сочетании с предыдущим параметром можно указать с привилегиями какого именно пользователя будет выполнена задача; vars_prompt — перед выполнением playbook'а Ansible в интерактивном режиме может уточнить указанные в этом разделе параметры; remote_user — имя пользователя для авторизации на удалённом узле; become — выполнить от имени привилегированного пользователя; become_user — имя привилегированного пользователя; when — условие выполнения; tags — теги, могут быть указаны при запуске playbook'а для выполнения конкретных задач; ignore_errors — игнорировать ошибки выполнения задачи и продолжать дальше. Debug и register Модуль debug имеет два возможных аргумента var — выводит значение переменной; msg — выводит текст, а также можно выводить значение переменной, в том числе встроенных в ansible, например owner. Все встроенные переменные можно посмотреть командой ansible group -m setup. Пример debug — - name: test-playbook
hosts: localhost
vars:
msg1: 123
msg2: 456
path: /home/123
tasks:
- debug:
var: path
var: ansible_os_family #выводит семейство ос
- debug:
msg: "string {{ owner }}"
#Объединить переменные в новую переменную и вывести
- set_fact: full_message="{{ msg1 }} {{ msg2 }} {{ owner }}"
msg: full_message Модуль register сохраняет выходные данные команд, он регистрирует в отдельный словарь с информацией о задаче, которую можно использовать дальше, всякая задача, выполняемая при запуске, может сохранить результаты в переменной. Для вывода информации в консоль можно использовать модуль debug.
Пример register — - name: test-playbook
hosts: localhost
tasks:
- shell: uptime
register: results
- debug:
var: results
var: results.stdout #выведет только вывод команды uptime Условия Для условия используется слово when
Пример when (true или false) — - name: test-playbook
hosts: localhost
vars:
var1: true
var2: false
tasks:
- name: Установка apache в centos
yum:
name: httpd
update_cache: true
state: present
when: var1
- name: Установка nginx в centos
yum:
name: httpd
update_cache: true
state: present
when: var2
Будет выполнена только первая задача. Пример when (сравнение переменной со значением) — - name: test-playbook
hosts: servers
tasks:
- name: Установка apache в centos
yum:
name: httpd
update_cache: true
state: present
when: ansible_os_family == "RedHat" #ansible_os_family - встроенная переменная
apt:
name: apache2
update_cache: true
state: present
when: ansible_os_family == "Debian" #или when: ansible_os_family != "RedHat"
- name: Запуск apache в centos
service:
name: httpd
state: started
enabled: true
when: ansible_os_family == "RedHat"
service:
name: apache2
state: started
enabled: true
when: ansible_os_family == "Debian" #или (when: ansible_os_family != "RedHat")
Можно сделать блоком предыдущий пример с использованием block — - name: test-playbook
hosts: servers
tasks:
- block:
- name: Установка apache в centos
yum:
name: httpd
update_cache: true
state: present
service:
name: httpd
state: started
enabled: true
when: ansible_os_family == "RedHat"
apt:
name: apache2
update_cache: true
state: present
service:
name: apache2
state: started
enabled: true
when: ansible_os_family == "Debian"
Шаблоны Jinja2 Шаблоны позволяют задавать переменные в файлах, которые будут скопированы на хосты. При копировании переменная заменяется значением.
Например есть файл template1.j2 со следующим содержимым Hostname: ansible_hostname #встроенные переменные OS family: ansible_os_faminy IP: ansible_default_ipv4.address my_var: my_var #своя переменная Тогда playbook будет следующим — - name: test-playbook
hosts: servers
vars: #своя переменная
my_var: example1
tasks:
- name: Копирование файла с подстановкой переменных
template:
src: /home/test1/template1.j2
dest: /home/test2/file1.txt #из шаблона получается файл с именем file1.txt с подставленными переменными
mode: 0644
Циклы Есть несколько вариантов цикла loop - цикл по количеству элементов списка; with_fileglob - цикл использующий файлы, которые соответствуют регулярному выражению; until - цикл с условием выхода. Цикл имеет зарезервированную переменную item, значение которой меняется каждую итерацию цикла.
Пример loop — - name: test-playbook
hosts: servers
tasks:
- name: Вывод 4 строк с цифрами
debug:
msg: "string {{ item }}" #item - это зарезервированное для цикла слово
loop:
- "1"
- "2"
- "3"
- "4"
loop_control:
pause: 3 #пауза в 3 секунды между итерациями цикла, можно не указывать
copy:
src: "/home/test1/{{ my_files }}"
dest: /home/test2
mode: 0644
loop:
- "file1.txt"
- "file5.txt"
- "file6.txt"
loop_control:
loop_var: my_files #замена стандартной переменной item на свою
Пример with_fileglob — - name: test-playbook
hosts: servers
tasks:
- name: Копирование файлов по регулярному выражению
copy:
src: "/home/test1/{{ item }}"
dest: /home/test2
mode: 0644
with_fileglob: "*.txt"
copy:
src: "{{ item }}"
dest: /home/test2
mode: 0644
with_fileglob: "/home/test1/*.txt"
Эти две задачи выполнят одно и тоже. Пример until — - name: test-playbook
hosts: servers
tasks:
- name: Второй вариант
shell: echo -n "123-" >> file1.txt && cat file1.txt #запись строки в файл и вывод в консоль
register: output #вывод предыдущей команды записывается в переменную output
delay: 2 #задержка 2 секунды между итерациями цикла, необязательно
retries: 10 #максимальное количество итераций цикла, необязательно, по умолчанию 3
until: output.stdout.find("123-123-123-") == false #условие выхода из цикла
debug:
var: output.stdout
Import и include Для разделения playbook'а используются import и include. Они позволяют в отдельном файле написать задачи на определенную тему, затем импортировать их в основной файл.
При использовании import - ansible берет текст файла перед запуском и проверяет на ошибки.
При использовании include содержимое файла берется только в момент прохода по этой команде, поэтому если используются переменные взятые из фактов нужно использовать include.
Например файл task_create.yaml содержит — - name: create file
file: dest: /home/file.txt state: touch owner: root group: root mode: 0644
А основной файл —
hosts: servers
tasks:
include: task_create.yaml #вместо include можно использовать import
myvar: "string" #можно передавать переменные в подключаемый файл
Роли Роли позволяют автоматически загружать связанные переменные, файлы, задачи, обработчики и другие артефакты Ansible на основе известной файловой структуры.
Роль Ansible имеет определенную структуру каталогов с восемью основными стандартными каталогами. Эту структуру можно сгенерировать командой ansible-galaxy init или создать каталоги самостоятельно Части playbook'а переносятся в соответствующие каталоги, затем в главной файле вызывается роль.
Список каталогов роли и их назначение tasks — задачи; handlers — задачи handlers; templates — шаблоны j2; files — файлы для копирования; vars — переменные, связанные с этой ролью; defaults — переменные по умолчанию, имеют самый низкий приоритет; meta — метаданные для роли, включая зависимости от роли; library — пользовательские модули; module_utils — пользовательские module_utils; lookup_plugins — дополнительные плагины. Основной файл — - name: test-playbook
hosts: servers roles: - role_name_1 - role_name_2
Внешние переменные Переменные, переданные в playbook через extra-var имеют наивысший приоритет. Передача значения переменной в playbook осуществляется с помощью ключа -e или –extra-var, например -e «message1=Hello».
Например, чтобы указывать на какой группе хостов запускать playbook, можно написать следующее — - name: test-playbook
hosts: "{{ hosts_run }}"
tasks:
- name: Создание файла
file:
dest: /home/file.txt
state: touch
owner: "{{ owner }}"
group: "{{ owner }}"
mode: 0644
И при запуске указывать значение переменной ansible-playbook main.yaml –extra-var «hosts_run=servers owner=root» Теги Ansible позволяет применять теги для выполнения определенных сценариев или задач к которым они привязаны. Для указания тегов при запуске playbook'а необходимо использовать ключ tags, за которым следует список нужных тегов.
ansible-playbook main.yaml –tags=test запуск сценария с передачей тега ansible-playbook main.yaml –skip-tags=test пропустить задачи с определенным тегом ansible-playbook main.yaml –list-tags проверить доступные теги Ansible имеет специальные теги: always - задача, помеченная этим тегом, всегда будет выполняться, даже если она не соответствует списку тегов, переданных в опции –tags. Единственное исключение ― когда он явно пропускается с помощью опции –skip-tags=always. never - задача, помеченная этим тегом, не выполняется, за исключением случая, когда выполняется набор сценариев с опцией –tags, в которой указано значение never или один из тегов, связанных с задачей. tagged - запускает любую задачу с явным тегом untagged - запускает любую задачу не имеющую явного тега all - включает все задачи в сценарии независимо от того, есть у них теги или нет. Это поведение Ansible по умолчанию. Выполнение задачи только на одном сервере Нужно написать у задачи delegate_to: server1 тогда задача выполнится только на указанном сервере.
Пример — - name: test-playbook
hosts: servers
tasks:
- name: Создание файла
file:
dest: /home/file.txt
state: touch
owner: root
group: root
mode: 0644
delegate_to: server1
С помощью этого можно сделать так, чтобы сервера направили некоторые свои данные на другой сервер, например — - name: test-playbook
hosts: servers
tasks:
- name: text
shell: echo "Server {{ inventory_hostname }} - node name {{ ansible_nodename }}" >> /home/log.txt
delegate_to: localhost
При выполнении на мастере создаться файл в который будут записаны значения переменных с других серверов. Если нужно запустить задачу только на одном сервере, но не важно на каком, нужно поставить флаг run_once: true, например — - name: test-playbook
hosts: servers
tasks:
- name: Создание файла
file:
dest: /home/file.txt
state: touch
owner: root
group: root
mode: 0644
run_once: true
Перехват и контроль ошибок При запуске playbook, если на одном из серверов какая-либо задаче не выполнилась, то все последующие задачи на этом сервере не будут выполнены, чтобы этого не произошло нужно добавить флаг ignore_errors: yes, тогда если в этой задаче произойдет ошибка последующие все равно будут выполняться.
--- - name: test-playbook hosts: servers tasks: - name: Создание файла file: dest: /home/file.txt state: touch owner: root group: root mode: 0644 ignore_errors: yes