Примеры Ansible для сетей
В этом документе описаны примеры использования Ansible для управления вашей сетевой инфраструктурой.
- Предварительные условия
-
Пример 1: сбор фактов и создание резервных файлов с помощью playbook
-
Пример 2: упрощение playbook с модулями, не зависящими от сети
- Устранение неполадок
Предварительные условия
Для этого примера требуется следующее:
- Ansible 2.10 (или выше) установлено. См. Установку Ansible для получения дополнительной информации.
- Один или несколько сетевых устройств, совместимых с Ansible.
- Основные знания YAML Синтаксис YAML.
- Основные знания шаблонов Jinja2. См. Шаблонизация (Jinja2) для получения дополнительной информации.
- Базовые навыки использования командной строки Linux.
- Базовые знания конфигурации сетевых коммутаторов и маршрутизаторов.
Группы и переменные в файле инвентаризации
Файл inventory — это файл конфигурации, подобный YAML или INI, который определяет сопоставление хостов с группами.
В нашем примере файл инвентаризации определяет группы eos, ios, vyos и «группу групп» switches. Дополнительные сведения о подгруппах и файлах инвентаризации см. в Документации по группам инвентаризации Ansible.
Поскольку Ansible — гибкий инструмент, есть несколько способов указать информацию о подключении и учетные данные. Рекомендуется использовать возможность [my_group:vars] в файле инвентаризации.
[all:vars] # these defaults can be overridden for any group in the [group:vars] section ansible_connection=ansible.netcommon.network_cli ansible_user=ansible [switches:children] eos ios vyos [eos] veos01 ansible_host=veos-01.example.net veos02 ansible_host=veos-02.example.net veos03 ansible_host=veos-03.example.net veos04 ansible_host=veos-04.example.net [eos:vars] ansible_become=yes ansible_become_method=enable ansible_network_os=arista.eos.eos ansible_user=my_eos_user ansible_password=my_eos_password [ios] ios01 ansible_host=ios-01.example.net ios02 ansible_host=ios-02.example.net ios03 ansible_host=ios-03.example.net [ios:vars] ansible_become=yes ansible_become_method=enable ansible_network_os=cisco.ios.ios ansible_user=my_ios_user ansible_password=my_ios_password [vyos] vyos01 ansible_host=vyos-01.example.net vyos02 ansible_host=vyos-02.example.net vyos03 ansible_host=vyos-03.example.net [vyos:vars] ansible_network_os=vyos.vyos.vyos ansible_user=my_vyos_user ansible_password=my_vyos_password
Если используется ssh-agent, строки ansible_password не требуются. Если используются ключи ssh, но не ssh-agent, и у вас несколько ключей, укажите используемый ключ для каждого подключения в разделе [group:vars] с помощью ansible_ssh_private_key_file=/path/to/correct/key. Дополнительные сведения об опциях ansible_ssh_ см. в Подключение к хостам: поведенческие параметры инвентаризации.
Предупреждение
Никогда не храните пароли в открытом виде.
Ansible vault для шифрования паролей
Функция «Vault» в Ansible позволяет хранить конфиденциальные данные, такие как пароли или ключи, в зашифрованных файлах вместо открытого текста в ваших playbook или ролях. Эти файлы vault можно затем распространять или размещать в системе контроля версий. Дополнительные сведения см. в Использование зашифрованных переменных и файлов.
Вот как это будет выглядеть, если вы укажете свои SSH-пароли (зашифрованные с помощью Ansible Vault) среди своих переменных:
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: vyos.vyos.vyos
ansible_user: my_vyos_user
ansible_ssh_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
39336231636137663964343966653162353431333566633762393034646462353062633264303765
6331643066663534383564343537343334633031656538370a333737656236393835383863306466
62633364653238323333633337313163616566383836643030336631333431623631396364663533
3665626431626532630a353564323566316162613432373738333064366130303637616239396438
9853
Общие переменные инвентаризации
Переменные, перечисленные ниже, являются общими для всех платформ в инвентаризации, хотя их можно перезаписать для конкретной группы инвентаризации или хоста.
- ansible_connection
-
Ansible использует параметр ansible-connection, чтобы определить способ подключения к удаленному устройству. При работе с Ansible Networking установите его на подходящий сетевой параметр подключения, например, ``ansible.netcommon.network_cli``, чтобы Ansible обрабатывал удаленный узел как сетевое устройство с ограниченной средой выполнения. Без этого параметра Ansible попытается подключиться по ssh к удаленному узлу и выполнить Python-скрипт на сетевом устройстве, что приведет к ошибке, поскольку Python обычно недоступен на сетевых устройствах.
- ansible_network_os
-
Указывает Ansible, к какой сетевой платформе относятся данные хосты. Это необходимо при использовании опций подключения
ansible.netcommon.*. - ansible_user
-
Пользователь, от имени которого происходит подключение к удаленному устройству (коммутатору). Если не указано, используется пользователь, выполняющий
ansible-playbook. Указывает пользователя на сетевом устройстве, с которым выполняется подключение. - ansible_password
-
Соответствующий пароль для
ansible_userдля входа. Если не указан, используется ключ SSH. - ansible_become
-
Если должен быть использован режим повышения привилегий (режим привилегий).
- ansible_become_method
-
Тип
becomeкоторый должен быть использован. Дляnetwork_cliединственный допустимый выбор —enable.
Масштабирование привилегий
Некоторые сетевые платформы, такие как Arista EOS и Cisco IOS, имеют понятие разных режимов привилегий. Некоторые сетевые модули, такие как те, которые изменяют состояние системы, включая пользователей, будут работать только в состояниях с высокими привилегиями. Ansible поддерживает become при использовании connection: ansible.netcommon.network_cli. Это позволяет повышать привилегии для конкретных задач, которым они необходимы. Добавление become: yes и become_method: enable сообщает Ansible перейти в режим повышенных привилегий перед выполнением задачи, как показано здесь:
[eos:vars] ansible_connection=ansible.netcommon.network_cli ansible_network_os=arista.eos.eos ansible_become=yes ansible_become_method=enable
Дополнительную информацию см. в руководстве использование become с сетевыми модулями.
Хосты-прокси
Если у контроллера Ansible нет прямого маршрута к удаленному устройству и вам нужен хост-прокси, ознакомьтесь с руководством Ansible Network Proxy Command для получения подробной информации о том, как это сделать.
Пример 1: сбор фактов и создание резервных файлов с помощью playbook
Модули фактов Ansible собирают информацию о системе «факты», которые доступны для остальной части вашего playbook.
Ansible Networking поставляется с рядом сетевых модулей фактов. В этом примере мы используем модули _facts arista.eos.eos_facts, cisco.ios.ios_facts и vyos.vyos.vyos_facts для подключения к удаленному сетевому устройству. Поскольку учетные данные не передаются явно в качестве аргументов модуля, Ansible использует имя пользователя и пароль из файла инвентаризации.
Сетевые модули фактов Ansible собирают информацию из системы и сохраняют результаты в фактах, начинающихся с ansible_net_. Данные, собранные этими модулями, описаны в разделе Return Values документации модуля, в данном случае arista.eos.eos_facts и vyos.vyos.vyos_facts. Мы можем использовать факты, такие как ansible_net_version, позже в задаче «Показать некоторые факты».
Чтобы убедиться, что мы вызываем правильный режим (*_facts), задача выполняется условно в зависимости от определенной в файле инвентаризации группы. Более подробная информация об использовании условных выражений в Ansible Playbook см. в Основные условные выражения с when.
В этом примере мы создадим файл инвентаризации с некоторыми сетевыми коммутаторами, а затем запустим playbook, чтобы подключиться к сетевым устройствам и получить некоторые сведения о них.
Шаг 1: Создание инвентаризации
Сначала создайте файл inventory, содержащий:
[switches:children] eos ios vyos [eos] eos01.example.net [ios] ios01.example.net [vyos] vyos01.example.net
Шаг 2: Создание playbook
Далее создайте файл playbook facts-demo.yml с приведенным ниже содержимым:
- name: "Demonstrate connecting to switches"
hosts: switches
gather_facts: no
tasks:
###
# Collect data
#
- name: Gather facts (eos)
arista.eos.eos_facts:
when: ansible_network_os == 'arista.eos.eos'
- name: Gather facts (ios)
cisco.ios.ios_facts:
when: ansible_network_os == 'cisco.ios.ios'
- name: Gather facts (vyos)
vyos.vyos.vyos_facts:
when: ansible_network_os == 'vyos.vyos.vyos'
###
# Demonstrate variables
#
- name: Display some facts
debug:
msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
- name: Facts from a specific host
debug:
var: hostvars['vyos01.example.net']
- name: Write facts to disk using a template
copy:
content: |
#jinja2: lstrip_blocks: True
EOS device info:
{% for host in groups['eos'] %}
Hostname: {{ hostvars[host].ansible_net_hostname }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
IOS device info:
{% for host in groups['ios'] %}
Hostname: {{ hostvars[host].ansible_net_hostname }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
VyOS device info:
{% for host in groups['vyos'] %}
Hostname: {{ hostvars[host].ansible_net_hostname }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
dest: /tmp/switch-facts
run_once: yes
###
# Get running configuration
#
- name: Backup switch (eos)
arista.eos.eos_config:
backup: yes
register: backup_eos_location
when: ansible_network_os == 'arista.eos.eos'
- name: backup switch (vyos)
vyos.vyos.vyos_config:
backup: yes
register: backup_vyos_location
when: ansible_network_os == 'vyos.vyos.vyos'
- name: Create backup dir
file:
path: "/tmp/backups/{{ inventory_hostname }}"
state: directory
recurse: yes
- name: Copy backup files into /tmp/backups/ (eos)
copy:
src: "{{ backup_eos_location.backup_path }}"
dest: "/tmp/backups/{{ inventory_hostname }}/{{ inventory_hostname }}.bck"
when: ansible_network_os == 'arista.eos.eos'
- name: Copy backup files into /tmp/backups/ (vyos)
copy:
src: "{{ backup_vyos_location.backup_path }}"
dest: "/tmp/backups/{{ inventory_hostname }}/{{ inventory_hostname }}.bck"
when: ansible_network_os == 'vyos.vyos.vyos'
Шаг 3: Запуск playbook
Чтобы запустить playbook, выполните следующую команду в командной строке:
ansible-playbook -i inventory facts-demo.yml
Это должно вернуть вывод, похожий на следующий:
PLAY RECAP eos01.example.net : ok=7 changed=2 unreachable=0 failed=0 ios01.example.net : ok=7 changed=2 unreachable=0 failed=0 vyos01.example.net : ok=6 changed=2 unreachable=0 failed=0
Шаг 4: Проверка результатов выполнения книги задач
Далее, ознакомьтесь с содержимым файла, который мы создали, содержащего данные о коммутаторах:
cat /tmp/switch-facts
Вы также можете посмотреть резервные файлы:
find /tmp/backups
Если ansible-playbook завершится ошибкой, следуйте инструкциям по отладке в Руководстве по отладке и устранению неполадок сети.
Пример 2: упрощение книг задач с использованием платформонезависимых модулей
(Этот пример был изначально опубликован в блоге "Deep Dive on cli_command for Network Automation" Сеаном Каванагом -@IPvSean).
Если в вашей среде имеется две или более сетевых платформ, вы можете использовать платформонезависимые модули для упрощения ваших книг задач. Вы можете использовать платформонезависимые модули, такие как ansible.netcommon.cli_command или ansible.netcommon.cli_config, вместо платформоспецифичных модулей, таких как arista.eos.eos_config, cisco.ios.ios_config, и junipernetworks.junos.junos_config. Это уменьшает количество задач и условных операторов, необходимых в ваших книгах задач.
Примечание
Платформонезависимые модули требуют плагин подключения ansible.netcommon.network_cli.
Пример книги задач с платформоспецифичными модулями
Этот пример предполагает три платформы: Arista EOS, Cisco NXOS и Juniper JunOS. Без платформонезависимых модулей пример книги задач может содержать следующие три задачи с платформоспецифичными командами:
---
- name: Run Arista command
arista.eos.eos_command:
commands: show ip int br
when: ansible_network_os == 'arista.eos.eos'
- name: Run Cisco NXOS command
cisco.nxos.nxos_command:
commands: show ip int br
when: ansible_network_os == 'cisco.nxos.nxos'
- name: Run Vyos command
vyos.vyos.vyos_command:
commands: show interface
when: ansible_network_os == 'vyos.vyos.vyos'
Упрощенная книга задач с cli_command платформонезависимым модулем
Вы можете заменить эти платформоспецифичные модули платформонезависимым модулем ansible.netcommon.cli_command следующим образом:
---
- hosts: network
gather_facts: false
connection: ansible.netcommon.network_cli
tasks:
- name: Run cli_command on Arista and display results
block:
- name: Run cli_command on Arista
ansible.netcommon.cli_command:
command: show ip int br
register: result
- name: Display result to terminal window
debug:
var: result.stdout_lines
when: ansible_network_os == 'arista.eos.eos'
- name: Run cli_command on Cisco IOS and display results
block:
- name: Run cli_command on Cisco IOS
ansible.netcommon.cli_command:
command: show ip int br
register: result
- name: Display result to terminal window
debug:
var: result.stdout_lines
when: ansible_network_os == 'cisco.ios.ios'
- name: Run cli_command on Vyos and display results
block:
- name: Run cli_command on Vyos
ansible.netcommon.cli_command:
command: show interfaces
register: result
- name: Display result to terminal window
debug:
var: result.stdout_lines
when: ansible_network_os == 'vyos.vyos.vyos'
Если вы используете группы и group_vars по типу платформы, эту книгу задач можно ещё больше упростить до:
---
- name: Run command and print to terminal window
hosts: routers
gather_facts: false
tasks:
- name: Run show command
ansible.netcommon.cli_command:
command: "{{show_interfaces}}"
register: command_output
Вы можете найти полный пример этого с использованием group_vars и пример резервного копирования конфигурации на примерах платформонезависимых модулей.
Использование нескольких запросов с ansible.netcommon.cli_command
ansible.netcommon.cli_command также поддерживает несколько запросов.
---
- name: Change password to default
ansible.netcommon.cli_command:
command: "{{ item }}"
prompt:
- "New password"
- "Retype new password"
answer:
- "mypassword123"
- "mypassword123"
check_all: True
loop:
- "configure"
- "rollback"
- "set system root-authentication plain-text-password"
- "commit"
См. ansible.netcommon.cli_command для получения полной документации по этой команде.
Примечания по реализации
Демонстрационные переменные
Хотя эти задачи не нужны для записи данных на диск, они используются в этом примере для демонстрации некоторых способов доступа к фактам о заданных устройствах или именованном узле.
Ansible hostvars позволяет вам получить доступ к переменным из именованного узла. Без этого мы бы возвращали данные для текущего узла, а не именованного.
Для получения дополнительной информации см. Информация об Ansible: магические переменные.
Получение текущей конфигурации
Модули arista.eos.eos_config и vyos.vyos.vyos_config имеют опцию backup:, которая, если установлена, заставит модуль создать полную резервную копию текущей running-config с удалённого устройства перед внесением любых изменений. Резервный файл записывается в папку backup в корневой директории книги задач. Если директория не существует, она создаётся.
Чтобы продемонстрировать, как мы можем переместить резервный файл в другое место, мы регистрируем результат и перемещаем файл в путь, сохранённый в backup_path.
Обратите внимание, что при использовании переменных из задач таким образом мы используем двойные кавычки (") и двойные фигурные скобки ({{...}}) для того, чтобы Ansible понял, что это переменная.
Устранение неполадок
Если вы получаете ошибку подключения, проверьте инвентарь и книгу задач на наличие опечаток или отсутствующих строк. Если проблема сохраняется, следуйте инструкциям по отладке в Руководстве по отладке и устранению неполадок сети.
См. также
© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.11/network/user_guide/network_best_practices_2.5.html