Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
linux:ansible:error [2023/11/27 23:04] werwolf |
linux:ansible:error [2023/11/27 23:13] (текущий) werwolf [failed_when] |
||
|---|---|---|---|
| Строка 65: | Строка 65: | ||
| ====ignore_errors==== | ====ignore_errors==== | ||
| + | При запуске playbook, если на одном из серверов какая-либо задаче не выполнилась, то все последующие задачи на этом сервере не будут выполнены, чтобы этого не произошло нужно добавить флаг ignore_errors: yes, тогда если в этой задаче произойдет ошибка последующие все равно будут выполняться. | ||
| - | market.yandex.ru | + | <code bash> |
| - | РЕКЛАМА | + | |
| - | Главная | + | |
| - | 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 | + | |
| - | + | ||
| - | - name: Запуск apache в centos | + | |
| - | service: | + | |
| - | name: httpd | + | |
| - | state: started | + | |
| - | enabled: true | + | |
| - | tags: tag1, tag2 #Теги | + | |
| - | when: ansible_os_family == "RedHat" #Условие выполнения | + | |
| - | + | ||
| - | - name: Создание файла #Имя задачи | + | |
| - | 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 | + | |
| - | + | ||
| - | - debug: | + | |
| - | var: ansible_os_family #выводит семейство ос | + | |
| - | + | ||
| - | - debug: | + | |
| - | msg: "string {{ owner }}" | + | |
| - | + | ||
| - | #Объединить переменные в новую переменную и вывести | + | |
| - | - set_fact: full_message="{{ msg1 }} {{ msg2 }} {{ owner }}" | + | |
| - | + | ||
| - | - debug: | + | |
| - | msg: full_message | + | |
| - | Модуль register сохраняет выходные данные команд, он регистрирует в отдельный словарь с информацией о задаче, которую можно использовать дальше, всякая задача, выполняемая при запуске, может сохранить результаты в переменной. Для вывода информации в консоль можно использовать модуль debug. | + | |
| - | + | ||
| - | Пример register | + | |
| - | --- | + | |
| - | - name: test-playbook | + | |
| - | hosts: localhost | + | |
| - | tasks: | + | |
| - | - shell: uptime | + | |
| - | register: results | + | |
| - | + | ||
| - | - debug: | + | |
| - | var: results | + | |
| - | + | ||
| - | - debug: | + | |
| - | 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 - встроенная переменная | + | |
| - | + | ||
| - | - name: Установка apache в ubuntu | + | |
| - | 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" | + | |
| - | + | ||
| - | - name: Запуск apache в ubuntu | + | |
| - | 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 | + | |
| - | + | ||
| - | - name: Запуск apache в centos | + | |
| - | service: | + | |
| - | name: httpd | + | |
| - | state: started | + | |
| - | enabled: true | + | |
| - | when: ansible_os_family == "RedHat" | + | |
| - | + | ||
| - | - block: | + | |
| - | - name: Установка apache в ubuntu | + | |
| - | apt: | + | |
| - | name: apache2 | + | |
| - | update_cache: true | + | |
| - | state: present | + | |
| - | + | ||
| - | - name: Запуск apache в ubuntu | + | |
| - | 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 секунды между итерациями цикла, можно не указывать | + | |
| - | + | ||
| - | - name: Копирование нескольких файлов | + | |
| - | 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" | + | |
| - | + | ||
| - | - name: Копирование файлов по регулярному выражению | + | |
| - | 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 #условие выхода из цикла | + | |
| - | + | ||
| - | - name: Вывод output | + | |
| - | 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 | + | |
| - | А основной файл | + | |
| - | --- | + | |
| - | - name: test-playbook | + | |
| - | 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 | - name: test-playbook | ||
| Строка 470: | Строка 79: | ||
| group: root | group: root | ||
| mode: 0644 | mode: 0644 | ||
| - | delegate_to: server1 | + | ignore_errors: yes |
| - | С помощью этого можно сделать так, чтобы сервера направили некоторые свои данные на другой сервер, например | + | </code> |
| - | --- | + | |
| - | - name: test-playbook | + | ==== failed_when ==== |
| - | hosts: servers | + | Вы можете использовать ключевое слово error_when для управления поведением задачи |
| - | 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, тогда если в этой задаче произойдет ошибка последующие все равно будут выполняться. | + | |
| <code bash> | <code bash> | ||
| --- | --- | ||
| - | - name: test-playbook | + | - name: Test ansible |
| - | hosts: servers | + | hosts: all |
| + | become: yes | ||
| + | |||
| tasks: | tasks: | ||
| - | - name: Создание файла | + | - name: Tasks number1 |
| - | file: | + | yum: name=treeee state=present |
| - | dest: /home/file.txt | + | ignore_errors: yes |
| - | state: touch | + | |
| - | owner: root | + | - name: Tasks number2 |
| - | group: root | + | shell: echo Hellow world |
| - | mode: 0644 | + | register: results |
| - | ignore_errors: yes | + | failed_when: "'world' in results.stdout" |
| + | |||
| + | - debug: | ||
| + | var: results | ||
| + | |||
| + | - name: Tasks number3 | ||
| + | shell: echo Privet Man! | ||
| + | |||
| + | ... | ||
| </code> | </code> | ||
| + | |||
| + | |||