В свете значительных усовершенствований, реализованных в Ansible Engine 2.6, а также с учетом выхода Ansible Tower 3.3 и недавнего выпуска Ansible Engine 2.7, рассмотрим подробнее перспективы автоматизации сетей.

В этом посте:
Не забывайте, что выход каждой новой версии Ansible сопровождается обновлением руководства по портированию, которое значительно облегчит вам переход на новую версию.
Плагины подключения (connection plugins) – это то, что позволяет Ansible подключаться к целевым хостам, чтобы затем выполнять на них задачи. Начиная с версии Ansible 2.5 появился новый плагин такого типа, который называется network_cli. Он избавляет от необходимости использовать параметр provider и стандартизует порядок выполнения сетевых модулей, в результате чего плейбуки для сетевых устройств теперь оформляются, выполняются и работают точно так же, как и плейбуки для Linux-хостов. В свою очередь, для Ansible Tower исчезает разница между сетевыми устройствами и хостами, и ему больше не надо различать логины-пароли для сетевых устройств и для машин. Подробнее это разбиралось здесь, но если вкратце, то логины-пароли для Linux-сервера и коммутатора Arista EOS или маршрутизатор Cisco теперь можно использовать и хранить аналогичным образом.
В Ansible 2.5 подключаться через методы eAPI и NX-API можно было только с помощью старого метода provider. В Ansible 2.6 этого ограничения больше нет и можно свободно использовать высокоуровневый метод подключения httpapi. Давайте посмотрим, как это делается.
Вначале надо включить eAPI или NX-API на сетевом устройстве, чтобы затем можно было использовать метод httpapi. Это легко делается соответствующей командой Ansible, например, вот как включить eAPI на коммутаторе Arista EOS.
При подключении к реальному коммутатору Arista EOS команда show management api http-commands покажет, что API включен:
Приведенный ниже сценарий Ansible Playbook просто выполняет команду show version, а затем в секции debug возвращает только версию из JSON-вывода задачи.
Запуск это сценария приведет к следующему результату:
ПРИМЕЧАНИЕ: Arista eAPI не поддерживает сокращенные версии команд (типа «show ver» вместо «show version2), поэтому приходится писать их полностью. Дополнительные сведения о плагине подключения httpapi можно найти в документации.
Ansible 2.6 и вышедшая в октябре версия 2.7 предлагают семь новых модулей для автоматизации сети.
Модули net_get и net_put не привязаны к оборудованию какого-то конкретного производителя и просто копируют файлы с сетевого устройства и на устройства, используя стандартные протоколы передачи SCP или SFTP (задается параметром protocol). Оба этих модуля требуют использования метода подключения network_cli, а также работают, только если на контроллере установлен scp (pip install scp), а на сетевом устройства включен SCP или SFTP.
Будем считать, что в примере с нашим плейбуком, мы уже выполнили следующую команду на устройстве Leaf01:
Вот как выглядит плейбук с двумя задачами (первая копирует файл с устройства Leaf01, а вторая копирует файл на устройство Leaf01):
Сетевой протокол управления NETCONF (Network Configuration Protocol) разработан и стандартизован IETF. Согласно RFC 6241, NETCONF может использоваться для установки, манипулирования и удаления конфигураций сетевых устройств. NETCONF – это альтернатива командной строке SSH (network_cli) и API-интерфейсам наподобие Cisco NX-API или Arista eAPI (httpapi).
Для демонстрации новых модулей netconf мы вначале включим netconf на маршрутизаторах Juniper с помощью модуля junos_netconf. Netconf поддерживается не всех моделях сетевого оборудования, поэтому прежде чем его использовать, сверьтесь с документацией.
Juniper Networks предлагает Junos XML API Explorer для Operational Tags и для Configuration Tags. Рассмотрим пример операционного запроса, который Juniper Networks использует в своей документации иллюстрации RPC-запроса конкретного интерфейса.
Это легко транслируется на язык Ansible Playbook. get-interface-information – это RPC-вызов, а дополнительные параметры задаются как пары ключ-значение. В этом примере есть только один параметр – interface-name – и на нашем сетевом устройстве мы просто хотим посмотреть em1.0. Мы используем заданный ну ровне задачи параметр register, просто чтобы сохранить результаты, поэтому используем модуль debug и выводим результаты на экран терминала. Модуль netconf_rpc также позволяет транслировать XML-вывод прямо в JSON.
После запуска плейбука получим вот что:
Дополнительные сведения можно найти в Juniper Platform Guide и в документации по NETCONF.
Появившиеся в Ansible Engine 2.7 модули cli_command и cli_config также не привязаны к оборудованию какого-то конкретного производителя и могут применяться для автоматизации различных сетевых платформ. Они отталкиваются от значения переменной ansible_network_os (задается в файле inventory или в папке group_vars), чтобы использовать нужный плагин cliconf. Список всех значений переменной ansible_network_os приводится в документации. В этой версии Ansible по-прежнему можно использовать и старые модули для конкретных платформ, так что не торопитесь переписывать имеющие плейбуки. Дополнительные сведения можно найти в oфициальных руководствах по портированию.
Давайте посмотрим, как эти модули используются в Ansible Playbook. Этот плейбук будет запускаться на двух системах Cisco Cloud Services Routers (CSR) под управлением IOS-XE. Для переменной ansible_network_os в файле inventory задано значение ios.
Вот как используются cli_config и cli_command:
А вот вывод этого плейбука:
Обратите внимание, что эти модули являются идемпотентыми до тех пор, пока вы используете соответствующий синтаксис для соответствующих сетевых устройств.
Веб-интерфейс в Red Hat Ansible Tower 3.3 стал удобнее и функциональнее, позволяя меньше щелкать мышкой при выполнении различных задач.

Управление учетными данными, планировщик заданий, сценарии инвентаризации, управление доступом на основе ролей, уведомления и многое другое теперь собраны в главном меню в левой части экрана и доступны в один клик. Экран просмотра заданий Jobs View сразу отображает важную дополнительную информацию: кто и когда запускал задание; какие inventory отрабатывались в ходе его выполнения; из какого проекта был взят плейбук.
В Red Hat Ansible Tower 3.3 стало гораздо проще управлять логинами-паролями для сетевых устройств. В новом веб-интерфейсе команда Credentials расположена сразу в главном меню, в группе Resources.

В Ansible Tower 3.3 остался специальный, так называемый «сетевой» тип учетных данных (Network), который задает переменные среды ANSIBLE_NET_USERNAME и ANSIBLE_NET_PASSWORD, используемые в старом методе provider. Все это по-прежнему работает, как написано в документации, чтобы можно было использовать уже имеющиеся сценарии Ansible Playbooks, Однако для новых высокоуровневых методов подключения httpapi и network_cli сетевой тип учетных данных больше не нужен, поскольку теперь Ansible одинаково работает с логинами-паролями как при подключении к сетевым устройствам, так и что при подключении к Linxu-хостам. Поэтому для сетевых устройств теперь надо выбирать тип учетных данных Machine – просто выбираете его и вводите логин-пароль или предоставляете ключ SSH.

ПРИМЕЧАНИЕ: Ansible Tower шифрует пароль сразу после того, как вы сохраняете учетные данные.

Благодаря шифрованию учетные данные можно безопасно делегировать другим пользователям и группам – они просто не увидят и не узнают пароль. Дополнительные сведения о том, как работают учетные данные, какое шифрование при этом применяется, какие еще есть типы учетных данных (типа Amazon AWS, Microsoft Azure и Google GCE) можно найти в документации по Ansible Tower.
Более подробное описание Red Hat Ansible Tower 3.3 можно найти здесь.
Допустим, мы хотим, чтобы одни плейбуки выполнялись через Ansible Engine 2.4.2, а другие – через Ansible Engine 2.6.4. В Tower есть для этого специальный инструмент virtualenv для создания изолированных сред Python во избежание проблем с конфликтующими зависимостями и отличающимися версиями. Ansible Tower 3.3 позволяет задавать virtualenv на разных уровнях – Organization, Project или Job Template. Вот как выглядит Job Template, который мы создали в Ansible Tower для резервного копирования нашей сети.

Когда у вас есть хотя бы две виртуальные среды, то в главном меню Ansible Tower появляется раскрывающее меню Ansible Environment, где можно легко задать, какая версия Ansible должна использоваться при выполнении задания.

Поэтому, если у вас есть микс из плейбуков для автоматизации сети, часть из которых использует старый метод provider (Ansible 2.4 и предыдущие версии), а часть – новые плагины httpapi или network_cli (Ansible 2.5 и выше), вы можете легко назначить каждому заданию необходимую версию Ansible. Кроме того, эта возможность будет полезна, если разработчики и продакшн используют разные версии Ansible. Иначе говоря, вы можете спокойно обновлять Tower, не беспокоясь, что после этого придется переходить на какую-то одну версию Ansible Engine, что сильно повышает гибкость при автоматизации различных типов сетевого оборудования и сред, а также сценариев использования.
Дополнительные сведения по использованию virtualenv можно найти в документации.

В этом посте:
- Плагин подключения httpapi.
- Поддержка Arista eAPI и Cisco NX-API.
- Новые модули сетевой автоматизации.
- net_get и net_put.
- netconf_get, netconf_rpc и netconf_config.
- cli_command и cli_config.
- Улучшенный веб-интерфейс Ansible Tower.
- Управление учетными данными в Ansible Tower при работе с сетевыми устройствам.
- Одновременное использование различных версий Ansible в Tower
Не забывайте, что выход каждой новой версии Ansible сопровождается обновлением руководства по портированию, которое значительно облегчит вам переход на новую версию.
Плагин подключения HTTPAPI
Плагины подключения (connection plugins) – это то, что позволяет Ansible подключаться к целевым хостам, чтобы затем выполнять на них задачи. Начиная с версии Ansible 2.5 появился новый плагин такого типа, который называется network_cli. Он избавляет от необходимости использовать параметр provider и стандартизует порядок выполнения сетевых модулей, в результате чего плейбуки для сетевых устройств теперь оформляются, выполняются и работают точно так же, как и плейбуки для Linux-хостов. В свою очередь, для Ansible Tower исчезает разница между сетевыми устройствами и хостами, и ему больше не надо различать логины-пароли для сетевых устройств и для машин. Подробнее это разбиралось здесь, но если вкратце, то логины-пароли для Linux-сервера и коммутатора Arista EOS или маршрутизатор Cisco теперь можно использовать и хранить аналогичным образом.
В Ansible 2.5 подключаться через методы eAPI и NX-API можно было только с помощью старого метода provider. В Ansible 2.6 этого ограничения больше нет и можно свободно использовать высокоуровневый метод подключения httpapi. Давайте посмотрим, как это делается.
Вначале надо включить eAPI или NX-API на сетевом устройстве, чтобы затем можно было использовать метод httpapi. Это легко делается соответствующей командой Ansible, например, вот как включить eAPI на коммутаторе Arista EOS.
[user@rhel7]$ ansible -m eos_eapi -c network_cli leaf01 leaf01 | SUCCESS => { "ansible_facts": { "eos_eapi_urls": { "Ethernet1": [ "https://192.168.0.14:443" ], "Management1": [ "https://10.0.2.15:443" ] } }, "changed": false, "commands": [] }
При подключении к реальному коммутатору Arista EOS команда show management api http-commands покажет, что API включен:
leaf01# show management api http-commands Enabled: Yes HTTPS server: running, set to use port 443 <<<rest of output removed for brevity>>>
Приведенный ниже сценарий Ansible Playbook просто выполняет команду show version, а затем в секции debug возвращает только версию из JSON-вывода задачи.
--- - hosts: leaf01 connection: httpapi gather_facts: false tasks: - name: type a simple arista command eos_command: commands: - show version | json register: command_output - name: print command output to terminal window debug: var: command_output.stdout[0]["version"]
Запуск это сценария приведет к следующему результату:
[user@rhel7]$ ansible-playbook playbook.yml PLAY [leaf01]******************************************************** TASK [type a simple arista command] ********************************* ok: [leaf01] TASK [print command output to terminal window] ********************** ok: [leaf01] => { "command_output.stdout[0][\"version\"]": "4.20.1F" } PLAY RECAP*********************************************************** leaf01 : ok=2 changed=0 unreachable=0 failed=0
ПРИМЕЧАНИЕ: Arista eAPI не поддерживает сокращенные версии команд (типа «show ver» вместо «show version2), поэтому приходится писать их полностью. Дополнительные сведения о плагине подключения httpapi можно найти в документации.
Новые модули автоматизации сети
Ansible 2.6 и вышедшая в октябре версия 2.7 предлагают семь новых модулей для автоматизации сети.
- net_get – копирует файл с сетевого устройства на Ansible Controller.
- net_put – копирует файл из Ansible Controller на сетевое устройство.
- netconf_get – извлекает конфигурацию/данные о состоянии из сетевого устройства с включенным NETCONF.
- netconf_rpc – выполняет операции на сетевом устройства с включенным NETCONF.
- netconf_config – конфигурация устройства netconf, модуль позволяет пользователю отправить XML-файл на устройства netconf и проверить, изменилась ли конфигурация.
- cli_command – запускает команду cli на сетевых устройствах, имеющих интерфейс командной (cli).
- cli_config – отправляет (push) текстовую конфигурацию на сетевые устройства через network_cli.
net_get и net_put
- net_get – копирует файл с сетевого устройства на Ansible Controller.
- net_put – копирует файл из Ansible Controller на сетевое устройство.
Модули net_get и net_put не привязаны к оборудованию какого-то конкретного производителя и просто копируют файлы с сетевого устройства и на устройства, используя стандартные протоколы передачи SCP или SFTP (задается параметром protocol). Оба этих модуля требуют использования метода подключения network_cli, а также работают, только если на контроллере установлен scp (pip install scp), а на сетевом устройства включен SCP или SFTP.
Будем считать, что в примере с нашим плейбуком, мы уже выполнили следующую команду на устройстве Leaf01:
leaf01#copy running-config flash:running_cfg_eos1.txt Copy completed successfully.
Вот как выглядит плейбук с двумя задачами (первая копирует файл с устройства Leaf01, а вторая копирует файл на устройство Leaf01):
--- - hosts: leaf01 connection: network_cli gather_facts: false tasks: - name: COPY FILE FROM THE NETWORK DEVICE TO ANSIBLE CONTROLLER net_get: src: running_cfg_eos1.txt - name: COPY FILE FROM THE ANSIBLE CONTROLLER TO THE NETWORK DEVICE net_put: src: temp.txt
netconf_get, netconf_rpc и netconf_config
- netconf_get – извлекает конфигурацию/данные о состоянии из сетевого устройства с включенным NETCONF.
- netconf_rpc – выполняет операции на сетевом устройства с включенным NETCONF.
- netconf_config – конфигурация устройства netconf, модуль позволяет пользователю отправить XML-файл на устройства netconf и проверить, изменилась ли конфигурация.
Сетевой протокол управления NETCONF (Network Configuration Protocol) разработан и стандартизован IETF. Согласно RFC 6241, NETCONF может использоваться для установки, манипулирования и удаления конфигураций сетевых устройств. NETCONF – это альтернатива командной строке SSH (network_cli) и API-интерфейсам наподобие Cisco NX-API или Arista eAPI (httpapi).
Для демонстрации новых модулей netconf мы вначале включим netconf на маршрутизаторах Juniper с помощью модуля junos_netconf. Netconf поддерживается не всех моделях сетевого оборудования, поэтому прежде чем его использовать, сверьтесь с документацией.
[user@rhel7 ~]$ ansible -m junos_netconf juniper -c network_cli rtr4 | CHANGED => { "changed": true, "commands": [ "set system services netconf ssh port 830" ] } rtr3 | CHANGED => { "changed": true, "commands": [ "set system services netconf ssh port 830" ] }
Juniper Networks предлагает Junos XML API Explorer для Operational Tags и для Configuration Tags. Рассмотрим пример операционного запроса, который Juniper Networks использует в своей документации иллюстрации RPC-запроса конкретного интерфейса.
<rpc> <get-interface-information> <interface-name>ge-2/3/0</interface-name> <detail/> </get-interface-information> </rpc> ]]>]]>
Это легко транслируется на язык Ansible Playbook. get-interface-information – это RPC-вызов, а дополнительные параметры задаются как пары ключ-значение. В этом примере есть только один параметр – interface-name – и на нашем сетевом устройстве мы просто хотим посмотреть em1.0. Мы используем заданный ну ровне задачи параметр register, просто чтобы сохранить результаты, поэтому используем модуль debug и выводим результаты на экран терминала. Модуль netconf_rpc также позволяет транслировать XML-вывод прямо в JSON.
--- - name: RUN A NETCONF COMMAND hosts: juniper gather_facts: no connection: netconf tasks: - name: GET INTERFACE INFO netconf_rpc: display: json rpc: get-interface-information content: interface-name: "em1.0" register: netconf_info - name: PRINT OUTPUT TO TERMINAL WINDOW debug: var: netconf_info
После запуска плейбука получим вот что:
ok: [rtr4] => { "netconf_info": { "changed": false, "failed": false, "output": { "rpc-reply": { "interface-information": { "logical-interface": { "address-family": [ { "address-family-flags": { "ifff-is-primary": "" }, "address-family-name": "inet", "interface-address": [ { "ifa-broadcast": "10.255.255.255", "ifa-destination": "10/8", "ifa-flags": { "ifaf-current-preferred": "" }, "ifa-local": "10.0.0.4" }, <<<rest of output removed for brevity>>>
Дополнительные сведения можно найти в Juniper Platform Guide и в документации по NETCONF.
cli_command и cli_config
- cli_command – запускает команду на сетевых устройствах, используя их интерфейс командной строки (если такой там есть).
- cli_config – отправляет (push) текстовую конфигурацию на сетевые устройства через network_cli.
Появившиеся в Ansible Engine 2.7 модули cli_command и cli_config также не привязаны к оборудованию какого-то конкретного производителя и могут применяться для автоматизации различных сетевых платформ. Они отталкиваются от значения переменной ansible_network_os (задается в файле inventory или в папке group_vars), чтобы использовать нужный плагин cliconf. Список всех значений переменной ansible_network_os приводится в документации. В этой версии Ansible по-прежнему можно использовать и старые модули для конкретных платформ, так что не торопитесь переписывать имеющие плейбуки. Дополнительные сведения можно найти в oфициальных руководствах по портированию.

Давайте посмотрим, как эти модули используются в Ansible Playbook. Этот плейбук будет запускаться на двух системах Cisco Cloud Services Routers (CSR) под управлением IOS-XE. Для переменной ansible_network_os в файле inventory задано значение ios.
<config snippet from inventory> [cisco] rtr1 ansible_host=34.203.197.120 rtr2 ansible_host=34.224.60.230 [cisco:vars] ansible_ssh_user=ec2-user ansible_network_os=ios
Вот как используются cli_config и cli_command:
--- - name: AGNOSTIC PLAYBOOK hosts: cisco gather_facts: no connection: network_cli tasks: - name: CONFIGURE DNS cli_config: config: ip name-server 8.8.8.8 - name: CHECK CONFIGURATION cli_command: command: show run | i ip name-server register: cisco_output - name: PRINT OUTPUT TO SCREEN debug: var: cisco_output.stdout
А вот вывод этого плейбука:
[user@rhel7 ~]$ ansible-playbook cli.yml PLAY [AGNOSTIC PLAYBOOK] ********************************************* TASK [CONFIGURE DNS] ************************************************* ok: [rtr1] ok: [rtr2] TASK [CHECK CONFIGURATION] ******************************************* ok: [rtr1] ok: [rtr2] TASK [PRINT OUTPUT TO SCREEN] **************************************** ok: [rtr1] => { "cisco_output.stdout": "ip name-server 8.8.8.8" } ok: [rtr2] => { "cisco_output.stdout": "ip name-server 8.8.8.8" } PLAY RECAP ********************************************************** rtr1 : ok=3 changed=0 unreachable=0 failed=0 rtr2 : ok=3 changed=0 unreachable=0 failed=0
Обратите внимание, что эти модули являются идемпотентыми до тех пор, пока вы используете соответствующий синтаксис для соответствующих сетевых устройств.
Улучшенный интерфейс Ansible Tower
Веб-интерфейс в Red Hat Ansible Tower 3.3 стал удобнее и функциональнее, позволяя меньше щелкать мышкой при выполнении различных задач.

Управление учетными данными, планировщик заданий, сценарии инвентаризации, управление доступом на основе ролей, уведомления и многое другое теперь собраны в главном меню в левой части экрана и доступны в один клик. Экран просмотра заданий Jobs View сразу отображает важную дополнительную информацию: кто и когда запускал задание; какие inventory отрабатывались в ходе его выполнения; из какого проекта был взят плейбук.

Управление учетными данными для сетевых устройств в Ansible Tower
В Red Hat Ansible Tower 3.3 стало гораздо проще управлять логинами-паролями для сетевых устройств. В новом веб-интерфейсе команда Credentials расположена сразу в главном меню, в группе Resources.

В Ansible Tower 3.3 остался специальный, так называемый «сетевой» тип учетных данных (Network), который задает переменные среды ANSIBLE_NET_USERNAME и ANSIBLE_NET_PASSWORD, используемые в старом методе provider. Все это по-прежнему работает, как написано в документации, чтобы можно было использовать уже имеющиеся сценарии Ansible Playbooks, Однако для новых высокоуровневых методов подключения httpapi и network_cli сетевой тип учетных данных больше не нужен, поскольку теперь Ansible одинаково работает с логинами-паролями как при подключении к сетевым устройствам, так и что при подключении к Linxu-хостам. Поэтому для сетевых устройств теперь надо выбирать тип учетных данных Machine – просто выбираете его и вводите логин-пароль или предоставляете ключ SSH.

ПРИМЕЧАНИЕ: Ansible Tower шифрует пароль сразу после того, как вы сохраняете учетные данные.

Благодаря шифрованию учетные данные можно безопасно делегировать другим пользователям и группам – они просто не увидят и не узнают пароль. Дополнительные сведения о том, как работают учетные данные, какое шифрование при этом применяется, какие еще есть типы учетных данных (типа Amazon AWS, Microsoft Azure и Google GCE) можно найти в документации по Ansible Tower.
Более подробное описание Red Hat Ansible Tower 3.3 можно найти здесь.
Одновременное использование различных версий Ansible в Tower
Допустим, мы хотим, чтобы одни плейбуки выполнялись через Ansible Engine 2.4.2, а другие – через Ansible Engine 2.6.4. В Tower есть для этого специальный инструмент virtualenv для создания изолированных сред Python во избежание проблем с конфликтующими зависимостями и отличающимися версиями. Ansible Tower 3.3 позволяет задавать virtualenv на разных уровнях – Organization, Project или Job Template. Вот как выглядит Job Template, который мы создали в Ansible Tower для резервного копирования нашей сети.

Когда у вас есть хотя бы две виртуальные среды, то в главном меню Ansible Tower появляется раскрывающее меню Ansible Environment, где можно легко задать, какая версия Ansible должна использоваться при выполнении задания.

Поэтому, если у вас есть микс из плейбуков для автоматизации сети, часть из которых использует старый метод provider (Ansible 2.4 и предыдущие версии), а часть – новые плагины httpapi или network_cli (Ansible 2.5 и выше), вы можете легко назначить каждому заданию необходимую версию Ansible. Кроме того, эта возможность будет полезна, если разработчики и продакшн используют разные версии Ansible. Иначе говоря, вы можете спокойно обновлять Tower, не беспокоясь, что после этого придется переходить на какую-то одну версию Ansible Engine, что сильно повышает гибкость при автоматизации различных типов сетевого оборудования и сред, а также сценариев использования.
Дополнительные сведения по использованию virtualenv можно найти в документации.
