Синтаксис playbook#

Playbook описываются в формате YAML.

Пример синтаксиса playbook#

Все примеры этого раздела находятся в каталоге 2_playbook_basics

Пример plabook 1_show_commands.yml:

---

- name: Run show commands on routers
  hosts: cisco_routers
  gather_facts: false

  tasks:

    - name: run sh ip int br
      ios_command:
        commands: sh ip int br

    - name: run sh ip arp
      ios_command:
        commands: sh ip arp


- name: Run command on R1
  hosts: 192.168.100.1
  gather_facts: false

  tasks:

    - name: run sh int status
      ios_command:
        commands: sh clock

В playbook два сценария (play):

  • name: Run show commands on routers - имя сценария (play). Этот параметр обязательно должен быть в любом сценарии

  • hosts: cisco_routers - сценарий будет применяться к устройствам в группе cisco-routers. Тут может быть указано и несколько групп, например, таким образом: hosts: cisco_routers:cisco_switches. Подробнее в документации

  • gather_facts: false - отключение сбора фактов об устройстве, так как для сетевого оборудования надо использовать отдельные модули для сбора фактов.

    • в разделе «конфигурационный файл» рассматривалось, как отключить сбор фактов по умолчанию. Если он отключен, то параметр gather_facts в play не нужно указывать.

  • tasks: - дальше идет перечень задач

    • в каждой задаче настроено имя (опционально) и действие. Действие может быть только одно.

    • в действии указывается, какой модуль использовать, и параметры модуля.

И тот же playbook с отображением элементов:

https://raw.githubusercontent.com/natenka/PyNEng/master/images/15_ansible/playbook.png

Так выглядит выполнение playbook:

$ ansible-playbook 1_show_commands.yml
https://raw.githubusercontent.com/natenka/PyNEng/master/images/15_ansible/playbook_execution.png

Обратите внимание, что для запуска playbook используется другая команда. Для ad-hoc команды использовалась команда ansible. А для playbook - ansible-playbook.

Для того, чтобы убедиться, что команды, которые указаны в задачах, выполнились на устройствах, запустите playbook с опцией -v (вывод сокращен):

$ ansible-playbook 1_show_commands.yml -v
https://raw.githubusercontent.com/natenka/PyNEng/master/images/15_ansible/playbook-verbose.png

В следующих разделах мы научимся отображать эти данные в нормальном формате и посмотрим, что с ними можно делать.

Порядок выполнения задач и сценариев#

Сценарии (play) и задачи (task) выполняются последовательно, в том порядке, в котором они описаны в playbook.

Если в сценарии, например, две задачи, то сначала первая задача должна быть выполнена для всех устройств, которые указаны в параметре hosts. Только после того, как первая задача была выполнена для всех хостов, начинается выполнение второй задачи.

Если в ходе выполнения playbook возникла ошибка в задаче на каком-то устройстве, это устройство исключается, и другие задачи на нём выполняться не будут.

Например, заменим пароль пользователя cisco на cisco123 (правильный cisco) на маршрутизаторе 192.168.100.1 и запустим playbook заново:

$ ansible-playbook 1_show_commands.yml
https://raw.githubusercontent.com/natenka/PyNEng/master/images/15_ansible/playbook_failed_execution.png

Обратите внимание на ошибку в выполнении первой задачи для маршрутизатора 192.168.100.1.

Во второй задаче „TASK [run sh ip route]“, Ansible уже исключил маршрутизатор и выполняет задачу только для маршрутизаторов 192.168.100.2 и 192.168.100.3.

Параметр –limit позволяет ограничивать, для каких хостов или групп будет выполняться playbook, при этом не меняя сам playbook.

Например, таким образом playbook можно запустить только для маршрутизатора 192.168.100.1:

$ ansible-playbook 1_show_commands.yml --limit 192.168.100.1

Идемпотентность#

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

Из этого правила есть исключения. Например, модуль raw всегда вносит изменения.

Если, например, в задаче указано, что на сервер Linux надо установить пакет httpd, то он будет установлен только в том случае, если его нет. То есть, действие не будет повторяться снова и снова при каждом запуске, а лишь тогда, когда пакета нет.

Аналогично и с сетевым оборудованием. Если задача модуля - выполнить команду в конфигурационном режиме, а она уже есть на устройстве, модуль не будет вносить изменения.